1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * dialog-sheetobject-size.c:
6 * Andreas J. Guelzow <aguelzow@pyrshep.ca>
8 * (c) Copyright 2009 Andreas J. Guelzow <aguelzow@pyrshep.ca>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <gnumeric-config.h>
25 #include <glib/gi18n-lib.h>
33 #include <workbook-control.h>
37 #include <sheet-view.h>
38 #include <application.h>
39 #include <workbook-cmd-format.h>
40 #include <sheet-object-widget.h>
41 #include <sheet-object-impl.h>
42 #include <sheet-control-gui.h>
43 #include <widgets/gnm-so-anchor-mode-chooser.h>
47 #define SO_SIZE_DIALOG_KEY "so-size-dialog"
57 GtkWidget
*apply_button
;
58 GtkWidget
*cancel_button
;
68 GtkWidget
*print_check
;
69 GnmSOAnchorModeChooser
*modecombo
;
72 SheetObjectAnchor
*old_anchor
;
73 SheetObjectAnchor
*active_anchor
;
76 gboolean so_size_needs_restore
;
77 gboolean so_pos_needs_restore
;
78 gboolean so_name_changed
;
79 gboolean so_print_check_changed
;
80 gboolean so_mode_changed
;
84 cb_dialog_so_size_value_changed_update_points (GtkSpinButton
*spinbutton
,
87 gint value
= gtk_spin_button_get_value_as_int (spinbutton
);
88 double size_points
= value
* 72./gnm_app_display_dpi_get (FALSE
);
89 gchar
*pts
= g_strdup_printf ("%.2f",size_points
);
90 gtk_label_set_text (points
, pts
);
95 dialog_so_size_button_sensitivity (SOSizeState
*state
)
97 gboolean sensitive
= state
->so_size_needs_restore
||
98 state
->so_pos_needs_restore
||
99 state
->so_name_changed
||
100 state
->so_print_check_changed
||
101 state
->so_mode_changed
;
102 gtk_widget_set_sensitive
103 (state
->ok_button
, sensitive
);
104 gtk_widget_set_sensitive
105 (state
->apply_button
, sensitive
);
109 cb_dialog_so_size_destroy (SOSizeState
*state
)
111 if (state
->so_size_needs_restore
|| state
->so_pos_needs_restore
)
112 sheet_object_set_anchor (state
->so
, state
->old_anchor
);
113 g_free (state
->old_anchor
);
114 g_free (state
->active_anchor
);
115 g_free (state
->old_name
);
116 if (state
->so
!= NULL
)
117 g_object_unref (state
->so
);
118 if (state
->gui
!= NULL
)
119 g_object_unref (state
->gui
);
124 cb_dialog_so_size_cancel_clicked (G_GNUC_UNUSED GtkWidget
*button
,
127 gtk_widget_destroy (state
->dialog
);
132 cb_dialog_so_size_value_changed (G_GNUC_UNUSED GtkSpinButton
*spinbutton
,
136 int new_width
, new_height
;
139 width
= state
->coords
[2] - state
->coords
[0];
140 height
= state
->coords
[3] - state
->coords
[1];
141 if (width
< 0) width
= - width
;
142 if (height
< 0) height
= - height
;
144 new_width
= gtk_spin_button_get_value_as_int (state
->wspin
);
145 new_height
= gtk_spin_button_get_value_as_int (state
->hspin
);
146 dx
= gtk_spin_button_get_value_as_int (state
->xspin
);
147 dy
= gtk_spin_button_get_value_as_int (state
->yspin
);
149 state
->so_size_needs_restore
= (new_width
!= width
) || (new_height
!= height
);
150 state
->so_pos_needs_restore
= (dx
!= 0) || (dy
!= 0);
152 *(state
->active_anchor
) = *(state
->old_anchor
);
154 if (state
->so_size_needs_restore
|| state
->so_pos_needs_restore
) {
155 gdouble new_coords
[4];
157 new_coords
[0] = state
->coords
[0] + dx
;
158 new_coords
[1] = state
->coords
[1] + dy
;
159 new_coords
[2] = state
->coords
[2] + dx
;
160 new_coords
[3] = state
->coords
[3] + dy
;
161 if (new_coords
[0] < new_coords
[2])
162 new_coords
[2] = new_coords
[0] + new_width
;
164 new_coords
[0] = new_coords
[2] + new_width
;
165 if (new_coords
[1] < new_coords
[3])
166 new_coords
[3] = new_coords
[1] + new_height
;
168 new_coords
[1] = new_coords
[3] + new_height
;
170 scg_object_coords_to_anchor (state
->scg
, new_coords
,
171 state
->active_anchor
);
174 sheet_object_set_anchor (state
->so
, state
->active_anchor
);
176 dialog_so_size_button_sensitivity (state
);
180 dialog_so_size_load (SOSizeState
*state
)
182 g_free (state
->old_anchor
);
183 state
->old_anchor
= sheet_object_anchor_dup
184 (sheet_object_get_anchor (state
->so
));
185 scg_object_anchor_to_coords (state
->scg
,
188 state
->so_size_needs_restore
= FALSE
;
189 state
->so_pos_needs_restore
= FALSE
;
193 set_params (SheetObject
*so
, char *name
)
195 return go_undo_binary_new
196 (g_object_ref (so
), name
,
197 (GOUndoBinaryFunc
)sheet_object_set_name
,
198 g_object_unref
, g_free
);
202 set_print_flag (SheetObject
*so
, gboolean print
)
204 gboolean
*p_print
= g_new (gboolean
, 1);
207 return go_undo_binary_new
208 (g_object_ref (so
), p_print
,
209 (GOUndoBinaryFunc
)sheet_object_set_print_flag
,
210 g_object_unref
, g_free
);
214 set_mode (SheetObject
*so
, GnmSOAnchorMode mode
)
216 GnmSOAnchorMode
*p_mode
= g_new (GnmSOAnchorMode
, 1);
219 return go_undo_binary_new
220 (g_object_ref (so
), p_mode
,
221 (GOUndoBinaryFunc
)sheet_object_set_anchor_mode
,
222 g_object_unref
, g_free
);
226 cb_dialog_so_size_apply_clicked (G_GNUC_UNUSED GtkWidget
*button
,
230 GOUndo
*undo
= NULL
, *redo
= NULL
;
231 char const *undo_name
= NULL
;
234 if (state
->so_size_needs_restore
|| state
->so_pos_needs_restore
) {
235 char const *label
= state
->so_pos_needs_restore
?
236 _("Move Object") : _("Resize Object");
237 sheet_object_set_anchor (state
->so
, state
->old_anchor
);
238 if (!cmd_objects_move (GNM_WBC (state
->wbcg
),
239 g_slist_prepend (NULL
, state
->so
),
241 (NULL
, sheet_object_anchor_dup
242 (state
->active_anchor
)),
244 dialog_so_size_load (state
);
247 name
= gtk_entry_get_text (state
->nameentry
);
250 if (strcmp (name
, state
->old_name
) != 0) {
251 char *old_name
, *new_name
;
253 g_object_get (G_OBJECT (state
->so
), "name", &old_name
, NULL
);
254 undo
= go_undo_combine (undo
, set_params (state
->so
, old_name
));
256 new_name
= (*name
== '\0') ? NULL
: g_strdup (name
);
257 redo
= go_undo_combine (redo
, set_params (state
->so
, new_name
));
259 undo_name
= _("Set Object Name");
262 if (state
->so_print_check_changed
) {
263 gboolean val
= ((state
->so
->flags
& SHEET_OBJECT_PRINT
) != 0);
264 undo
= go_undo_combine (undo
, set_print_flag
266 redo
= go_undo_combine (redo
, set_print_flag
268 undo_name
= _("Set Object Print Property");
271 if (state
->so_mode_changed
) {
272 int new_mode
= gnm_so_anchor_mode_chooser_get_mode (state
->modecombo
);
273 int old_mode
= state
->so
->anchor
.mode
;
274 undo
= go_undo_combine (undo
, set_mode (state
->so
, old_mode
));
275 redo
= go_undo_combine (redo
, set_mode (state
->so
, new_mode
));
276 undo_name
= _("Set Object Anchor Mode");
282 undo_name
= _("Set Object Properties");
283 state
->so_name_changed
= state
->so_print_check_changed
= state
->so_mode_changed
=
284 cmd_generic (GNM_WBC (state
->wbcg
),
285 undo_name
, undo
, redo
);
287 dialog_so_size_button_sensitivity (state
);
293 cb_dialog_so_size_ok_clicked (GtkWidget
*button
, SOSizeState
*state
)
295 cb_dialog_so_size_apply_clicked (button
, state
);
296 if (!state
->so_size_needs_restore
&& !state
->so_pos_needs_restore
&&
297 !state
->so_name_changed
&& !state
->so_print_check_changed
)
298 gtk_widget_destroy (state
->dialog
);
303 cb_dialog_so_size_name_changed (GtkEntry
*entry
,
304 GdkEventFocus
*event
,
307 char const *name
= gtk_entry_get_text (entry
);
310 state
->so_name_changed
311 = (strcmp (name
, state
->old_name
) != 0);
312 dialog_so_size_button_sensitivity (state
);
317 cb_dialog_so_size_print_check_toggled (GtkToggleButton
*togglebutton
,
320 gboolean new_print
= !gtk_toggle_button_get_active (togglebutton
);
321 gboolean old_print
= ((state
->so
->flags
& SHEET_OBJECT_PRINT
) != 0);
323 state
->so_print_check_changed
324 = (new_print
!= old_print
);
325 dialog_so_size_button_sensitivity (state
);
330 cb_dialog_so_size_mode_changed (GnmSOAnchorModeChooser
*chooser
, SOSizeState
*state
)
332 GnmSOAnchorMode new_mode
= gnm_so_anchor_mode_chooser_get_mode (chooser
);
333 GnmSOAnchorMode old_mode
= state
->so
->anchor
.mode
;
336 scg_object_anchor_to_coords (state
->scg
, state
->active_anchor
, coords
);
337 state
->active_anchor
->mode
= new_mode
;
338 scg_object_coords_to_anchor (state
->scg
, coords
, state
->active_anchor
);
339 state
->so_mode_changed
= new_mode
!= old_mode
;
340 dialog_so_size_button_sensitivity (state
);
344 dialog_so_size (WBCGtk
*wbcg
, GObject
*so
)
351 g_return_if_fail (wbcg
!= NULL
);
353 if (gnm_dialog_raise_if_exists (wbcg
, SO_SIZE_DIALOG_KEY
))
355 gui
= gnm_gtk_builder_load ("sheetobject-size.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
359 state
= g_new (SOSizeState
, 1);
361 state
->sv
= wb_control_cur_sheet_view (GNM_WBC (wbcg
));
362 state
->sheet
= sv_sheet (state
->sv
);
363 state
->scg
= wbcg_get_nth_scg (wbcg
, state
->sheet
->index_in_wb
);
365 state
->dialog
= go_gtk_builder_get_widget (state
->gui
, "object-size");
367 state
->so
= GNM_SO (so
);
370 state
->nameentry
= GTK_ENTRY (go_gtk_builder_get_widget (state
->gui
, "name-entry"));
371 state
->old_anchor
= NULL
;
372 state
->old_name
= NULL
;
373 g_object_get (so
, "name", &state
->old_name
, NULL
);
374 if (state
->old_name
== NULL
)
375 state
->old_name
= g_strdup ("");
376 gtk_entry_set_text (state
->nameentry
, state
->old_name
);
377 state
->so_name_changed
= FALSE
;
378 g_signal_connect (G_OBJECT (state
->nameentry
),
380 G_CALLBACK (cb_dialog_so_size_name_changed
),
382 state
->so_print_check_changed
= FALSE
;
384 state
->wpoints
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "w-pts-label"));
385 state
->wspin
= GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state
->gui
, "w-spin"));
386 state
->hpoints
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "h-pts-label"));
387 state
->hspin
= GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state
->gui
, "h-spin"));
388 state
->xpoints
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "x-pts-label"));
389 state
->xspin
= GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state
->gui
, "x-spin"));
390 state
->ypoints
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "y-pts-label"));
391 state
->yspin
= GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state
->gui
, "y-spin"));
392 state
->print_check
= GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
,
394 state
->modecombo
= GNM_SO_ANCHOR_MODE_CHOOSER (gnm_so_anchor_mode_chooser_new (sheet_object_can_resize (state
->so
)));
395 dialog_so_size_load (state
);
396 state
->active_anchor
= sheet_object_anchor_dup (sheet_object_get_anchor
398 width
= state
->coords
[2] - state
->coords
[0];
399 height
= state
->coords
[3] - state
->coords
[1];
401 gtk_spin_button_set_value (state
->wspin
, (width
< 0) ? - width
: width
);
402 gtk_spin_button_set_value (state
->hspin
, (height
< 0) ? - height
: height
);
403 gtk_spin_button_set_value (state
->xspin
, 0.);
404 gtk_spin_button_set_value (state
->yspin
, 0.);
405 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state
->print_check
),
406 !(state
->so
->flags
& SHEET_OBJECT_PRINT
));
407 gnm_so_anchor_mode_chooser_set_mode (state
->modecombo
,
408 state
->so
->anchor
.mode
);
409 grid
= GTK_GRID (gtk_builder_get_object (state
->gui
, "main-grid"));
410 gtk_grid_insert_row (grid
, 7);
411 gtk_grid_attach (grid
, GTK_WIDGET (state
->modecombo
), 0, 7, 2, 1);
412 gtk_widget_set_halign (GTK_WIDGET (state
->modecombo
), GTK_ALIGN_START
);
413 gtk_widget_show (GTK_WIDGET (state
->modecombo
));
414 g_signal_connect (G_OBJECT (state
->wspin
),
416 G_CALLBACK (cb_dialog_so_size_value_changed_update_points
),
418 g_signal_connect (G_OBJECT (state
->hspin
),
420 G_CALLBACK (cb_dialog_so_size_value_changed_update_points
),
422 g_signal_connect (G_OBJECT (state
->xspin
),
424 G_CALLBACK (cb_dialog_so_size_value_changed_update_points
),
426 g_signal_connect (G_OBJECT (state
->yspin
),
428 G_CALLBACK (cb_dialog_so_size_value_changed_update_points
),
430 g_signal_connect (G_OBJECT (state
->print_check
),
432 G_CALLBACK (cb_dialog_so_size_print_check_toggled
),
435 cb_dialog_so_size_value_changed_update_points (state
->wspin
, GTK_LABEL (state
->wpoints
));
436 cb_dialog_so_size_value_changed_update_points (state
->hspin
, GTK_LABEL (state
->hpoints
));
437 cb_dialog_so_size_value_changed_update_points (state
->xspin
, GTK_LABEL (state
->xpoints
));
438 cb_dialog_so_size_value_changed_update_points (state
->yspin
, GTK_LABEL (state
->ypoints
));
441 g_signal_connect (G_OBJECT (state
->wspin
),
443 G_CALLBACK (cb_dialog_so_size_value_changed
), state
);
444 g_signal_connect (G_OBJECT (state
->hspin
),
446 G_CALLBACK (cb_dialog_so_size_value_changed
), state
);
447 g_signal_connect (G_OBJECT (state
->xspin
),
449 G_CALLBACK (cb_dialog_so_size_value_changed
), state
);
450 g_signal_connect (G_OBJECT (state
->yspin
),
452 G_CALLBACK (cb_dialog_so_size_value_changed
), state
);
454 g_signal_connect (G_OBJECT (state
->modecombo
),
456 G_CALLBACK (cb_dialog_so_size_mode_changed
), state
);
458 state
->ok_button
= go_gtk_builder_get_widget (state
->gui
, "ok_button");
459 g_signal_connect (G_OBJECT (state
->ok_button
),
461 G_CALLBACK (cb_dialog_so_size_ok_clicked
), state
);
462 state
->apply_button
= go_gtk_builder_get_widget (state
->gui
, "apply_button");
463 g_signal_connect (G_OBJECT (state
->apply_button
),
465 G_CALLBACK (cb_dialog_so_size_apply_clicked
), state
);
467 state
->cancel_button
= go_gtk_builder_get_widget (state
->gui
, "cancel_button");
468 g_signal_connect (G_OBJECT (state
->cancel_button
),
470 G_CALLBACK (cb_dialog_so_size_cancel_clicked
), state
);
472 gnm_init_help_button (
473 go_gtk_builder_get_widget (state
->gui
, "help_button"),
474 GNUMERIC_HELP_LINK_SO_SIZE
);
476 gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state
->dialog
),
478 GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED
);
480 wbc_gtk_attach_guru (state
->wbcg
, state
->dialog
);
481 g_object_set_data_full (G_OBJECT (state
->dialog
),
482 "state", state
, (GDestroyNotify
) cb_dialog_so_size_destroy
);
484 gnm_keyed_dialog (wbcg
, GTK_WINDOW (state
->dialog
),
486 dialog_so_size_button_sensitivity (state
);
487 gtk_widget_show (state
->dialog
);