2 * dialog-printer-setup.c: Printer setup dialog box
5 * Wayne Schuller (k_wayne@linuxpower.org)
6 * Miguel de Icaza (miguel@gnu.org)
7 * 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>
31 #include <print-info.h>
35 #include <sheet-object-graph.h>
39 #include <gnumeric-conf.h>
41 #include <gdk/gdkkeysyms.h>
42 #include <goffice/goffice.h>
45 #define PREVIEW_MARGIN_X 20
46 #define PREVIEW_MARGIN_Y 20
48 #define MARGIN_COLOR_DEFAULT 0xa9a9a9ff /* dark gray */
49 #define MARGIN_COLOR_ACTIVE GO_COLOR_RED
51 /* FIXME: do not hardcode pixel counts. */
52 #define HF_PREVIEW_X 350
53 #define HF_PREVIEW_Y 75
54 #define HF_PREVIEW_SHADOW 2
55 #define HF_PREVIEW_PADDING 5
56 #define HF_PREVIEW_MARGIN 10
58 #define PRINTER_SETUP_KEY "printer-setup-dialog"
64 #define HF_TAG_NAME "field_tag"
67 /* The Canvas object */
70 /* Objects in the Preview Canvas */
73 /* Values for the scaling of the nice preview */
75 int offset_x
, offset_y
; /* For centering the small page preview */
80 /* The available width and height for the nice preview page */
82 } MarginPreviewPageAvailableSize
;
85 /* The Canvas object for the header/footer sample preview */
88 /* Objects in the Preview Canvas */
96 typedef struct _PrinterSetupState PrinterSetupState
;
101 double bound_x1
, bound_y1
, bound_x2
, bound_y2
;
102 MarginPreviewInfo
*pi
;
103 PrinterSetupState
*state
;
106 struct _PrinterSetupState
{
110 GnmPrintInformation
*pi
;
112 GtkWidget
*sheet_selector
;
114 GtkWidget
*scale_percent_radio
;
115 GtkWidget
*scale_fit_to_radio
;
116 GtkWidget
*scale_no_radio
;
118 GtkWidget
*portrait_radio
;
119 GtkWidget
*landscape_radio
;
120 GtkWidget
*rev_portrait_radio
;
121 GtkWidget
*rev_landscape_radio
;
123 GtkWidget
*unit_selector
;
124 GtkTreeModel
*unit_model
;
125 GtkUnit display_unit
;
128 UnitInfo top
, bottom
, left
, right
;
129 UnitInfo header
, footer
;
132 MarginPreviewInfo preview
;
134 double height
, width
;
136 GtkWidget
* check_center_v
;
137 GtkWidget
* check_center_h
;
141 GnmExprEntry
*area_entry
;
142 GnmExprEntry
*top_entry
;
143 GnmExprEntry
*left_entry
;
145 /* The header and footer data. */
149 /* The header and footer customize dialogs. */
150 GtkWidget
*customize_header
;
151 GtkWidget
*customize_footer
;
153 /* The header and footer preview widgets. */
154 HFPreviewInfo
*pi_header
;
155 HFPreviewInfo
*pi_footer
;
163 /* Comment Display */
170 typedef struct _HFCustomizeState HFCustomizeState
;
172 typedef struct _HFDTFormatState HFDTFormatState
;
173 struct _HFDTFormatState
{
176 HFCustomizeState
*hf_state
;
178 GtkWidget
*format_sel
;
181 struct _HFCustomizeState
{
184 PrinterSetupState
*printer_setup_state
;
187 GtkTextBuffer
*left_buffer
;
188 GtkTextBuffer
*middle_buffer
;
189 GtkTextBuffer
*right_buffer
;
205 typedef struct _HFMarkInfo HFMarkInfo
;
212 static void dialog_gtk_printer_setup_cb (PrinterSetupState
*state
);
213 static void fetch_settings (PrinterSetupState
*state
);
214 static void do_update_page (PrinterSetupState
*state
);
215 static void do_fetch_margins (PrinterSetupState
*state
);
216 static void do_hf_customize (gboolean header
, PrinterSetupState
*state
);
217 static char *do_hf_dt_format_customize (gboolean date
, HFCustomizeState
*hf_state
);
221 get_conversion_factor (GtkUnit unit
)
229 case GTK_UNIT_POINTS
:
236 margin_preview_page_destroy (PrinterSetupState
*state
)
238 if (state
->preview
.group
) {
239 g_object_unref (state
->preview
.group
);
240 state
->preview
.group
= NULL
;
245 move_line (GocItem
*item
,
246 double x1
, double y1
,
247 double x2
, double y2
)
251 "x0", floor (x1
) + .5,
252 "y0", floor (y1
) + .5,
253 "x1", floor (x2
) + .5,
254 "y1", floor (y2
) + .5,
259 make_line (GocGroup
*g
, double x1
, double y1
, double x2
, double y2
)
265 item
= goc_item_new (
266 g
, goc_line_get_type (),
267 "x0", floor (x1
) + .5,
268 "y0", floor (y1
) + .5,
269 "x1", floor (x2
) + .5,
270 "y1", floor (y2
) + .5,
272 style
= go_styled_object_get_style (GO_STYLED_OBJECT (item
));
273 style
->line
.width
= 1.;
274 style
->line
.color
= MARGIN_COLOR_DEFAULT
;
280 draw_margin_top (UnitInfo
*uinfo
)
284 x1
= uinfo
->bound_x1
;
285 x2
= uinfo
->bound_x2
;
286 y1
= uinfo
->bound_y1
;
288 y1
+= uinfo
->pi
->scale
* uinfo
->value
;
289 move_line (uinfo
->line
, x1
, y1
, x2
, y1
);
293 draw_margin_bottom (UnitInfo
*uinfo
)
297 x1
= uinfo
->bound_x1
;
298 x2
= uinfo
->bound_x2
;
299 y2
= uinfo
->bound_y2
;
301 y2
-= uinfo
->pi
->scale
* uinfo
->value
;
302 move_line (uinfo
->line
, x1
, y2
, x2
, y2
);
306 draw_margin_left (UnitInfo
*uinfo
)
310 x1
= uinfo
->bound_x1
;
311 y1
= uinfo
->bound_y1
;
312 y2
= uinfo
->bound_y2
;
314 x1
+= uinfo
->pi
->scale
* uinfo
->value
;
315 move_line (uinfo
->line
, x1
, y1
, x1
, y2
);
319 draw_margin_right (UnitInfo
*uinfo
)
323 y1
= uinfo
->bound_y1
;
324 x2
= uinfo
->bound_x2
;
325 y2
= uinfo
->bound_y2
;
327 x2
-= uinfo
->pi
->scale
* uinfo
->value
;
328 move_line (uinfo
->line
, x2
, y1
, x2
, y2
);
332 draw_margin_header (UnitInfo
*uinfo
)
335 double outside
= uinfo
->pi
->scale
*
336 uinfo
->state
->margins
.top
.value
;
337 double inside
= uinfo
->pi
->scale
* uinfo
->value
;
339 x1
= uinfo
->bound_x1
;
340 y1
= uinfo
->bound_y1
;
341 x2
= uinfo
->bound_x2
;
345 y1
+= outside
+ inside
;
347 move_line (uinfo
->line
, x1
, y1
, x2
, y1
);
351 draw_margin_footer (UnitInfo
*uinfo
)
354 double outside
= uinfo
->pi
->scale
*
355 uinfo
->state
->margins
.bottom
.value
;
356 double inside
= uinfo
->pi
->scale
* uinfo
->value
;
358 x1
= uinfo
->bound_x1
;
359 x2
= uinfo
->bound_x2
;
360 y2
= uinfo
->bound_y2
;
364 y2
-= outside
+ inside
;
365 move_line (uinfo
->line
, x1
, y2
, x2
, y2
);
369 create_margin (UnitInfo
*uinfo
,
370 double x1
, double y1
,
371 double x2
, double y2
)
373 GocGroup
*g
= GOC_GROUP (uinfo
->state
->preview
.group
);
375 uinfo
->line
= make_line (g
, x1
+ 8, y1
, x1
+ 8, y2
);
376 uinfo
->bound_x1
= x1
;
377 uinfo
->bound_y1
= y1
;
378 uinfo
->bound_x2
= x2
;
379 uinfo
->bound_y2
= y2
;
383 draw_margins (PrinterSetupState
*state
, double x1
, double y1
, double x2
, double y2
)
386 create_margin (&state
->margins
.left
, x1
, y1
, x2
, y2
);
387 create_margin (&state
->margins
.right
, x1
, y1
, x2
, y2
);
388 create_margin (&state
->margins
.top
, x1
, y1
, x2
, y2
);
389 create_margin (&state
->margins
.bottom
, x1
, y1
, x2
, y2
);
391 /* Headers & footers */
392 create_margin (&state
->margins
.header
, x1
, y1
, x2
, y2
);
393 create_margin (&state
->margins
.footer
, x1
, y1
, x2
, y2
);
396 draw_margin_left (&state
->margins
.left
);
397 draw_margin_right (&state
->margins
.right
);
398 draw_margin_top (&state
->margins
.top
);
399 draw_margin_bottom (&state
->margins
.bottom
);
401 /* Headers & footers */
402 draw_margin_header (&state
->margins
.header
);
403 draw_margin_footer (&state
->margins
.footer
);
407 margin_preview_page_available_size (PrinterSetupState
*state
,
408 MarginPreviewPageAvailableSize
*available_size
)
412 unsigned *widths
, *heights
;
413 GtkRequisition requisition
;
414 unsigned top
, left
, width
, height
, i
;
415 unsigned nrows
, ncols
, first_col
, first_row
;
417 /* Reset available size to zero*/
418 available_size
->width
= 0;
419 available_size
->height
= 0;
421 grid
= go_gtk_builder_get_widget (state
->gui
, "paper-selector-grid");
422 gtk_container_child_get (GTK_CONTAINER (grid
),
423 go_gtk_builder_get_widget (state
->gui
, "container-paper-sample"),
424 "top-attach", &first_row
,
425 "left-attach", &first_col
,
429 widths
= g_new0 (guint
, ncols
);
430 heights
= g_new0 (guint
, nrows
);
432 /* Iterate through all child widgets in the grid */
433 children
= gtk_container_get_children (GTK_CONTAINER (grid
));
434 for (l
= children
; l
; l
= l
->next
) {
435 GtkWidget
*child_widget
= l
->data
;
437 /* Determine which cells the align widget spans across */
438 gtk_container_child_get (GTK_CONTAINER (grid
), GTK_WIDGET (child_widget
),
440 "left-attach", &left
,
445 /* Determine the requisition size for the widget */
446 gtk_widget_get_preferred_size (GTK_WIDGET(child_widget
), &requisition
, NULL
);
448 /* Find largest widget in each table column */
449 /* Exclude widgets that expand across more than one grid cells
450 * or are not in a relevant column */
451 if (left
>= first_col
&& width
== 1 && left
< first_col
+ ncols
) {
452 if ((guint
) requisition
.width
> widths
[left
- first_col
]) {
453 widths
[left
- first_col
] = (guint
) requisition
.width
;
457 /* Find largest widget in each table row */
458 /* Exclude widgets that expand across more than one grid cells
459 * or are not in a relevant column */
460 if (top
>= first_row
&& height
== 1 && top
< first_row
+ nrows
) {
461 if ((guint
) requisition
.height
> heights
[top
- first_row
]) {
462 heights
[top
- first_row
] = (guint
) requisition
.height
;
466 g_list_free (children
);
468 /* Calculate width of container widget using maximum */
469 /* widget widths from above */
470 for (i
= 0; i
< ncols
; i
++){
471 available_size
->width
= available_size
->width
+ widths
[i
];
474 /* Calculate height of container widget using maximum */
475 /* widget heights from above */
476 for (i
= 0; i
< nrows
; i
++){
477 available_size
->height
= available_size
->height
+ heights
[i
];
483 /* Account for the spacing between table cells */
484 available_size
->width
= available_size
->width
+
485 gtk_grid_get_column_spacing (GTK_GRID (grid
)) * (ncols
- 1);
486 available_size
->height
= available_size
->height
+
487 gtk_grid_get_row_spacing (GTK_GRID (grid
)) * (nrows
- 1);
491 margin_preview_page_create (PrinterSetupState
*state
)
493 double x1
, y1
, x2
, y2
;
494 double width
, height
;
495 MarginPreviewInfo
*pi
= &state
->preview
;
497 MarginPreviewPageAvailableSize margin_available_size
;
499 margin_preview_page_available_size (state
, &margin_available_size
);
500 gtk_widget_set_size_request (state
->preview
.canvas
, margin_available_size
.width
, margin_available_size
.height
);
502 width
= state
->width
;
503 height
= state
->height
;
504 x1
= (margin_available_size
.width
- PREVIEW_MARGIN_X
) / width
;
505 x2
= (margin_available_size
.height
- PREVIEW_MARGIN_Y
) / height
;
506 pi
->scale
= MIN (x1
, x2
);
508 pi
->offset_x
= (margin_available_size
.width
- (width
* pi
->scale
)) / 2;
509 pi
->offset_y
= (margin_available_size
.height
- (height
* pi
->scale
)) / 2;
512 x2
= pi
->offset_x
+ width
* pi
->scale
;
513 y2
= pi
->offset_y
+ height
* pi
->scale
;
515 pi
->group
= goc_item_new (
516 goc_canvas_get_root (GOC_CANVAS (pi
->canvas
)),
517 goc_group_get_type (),
522 style
= go_styled_object_get_style (
523 GO_STYLED_OBJECT (goc_item_new (GOC_GROUP (pi
->group
),
527 "width", (double) x2
-x1
,
528 "height", (double) y2
-y1
,
530 style
->fill
.pattern
.back
= GO_COLOR_BLACK
;
531 style
->line
.color
= GO_COLOR_BLACK
;
532 style
->line
.width
= 1.;
534 style
= go_styled_object_get_style (
535 GO_STYLED_OBJECT (goc_item_new (GOC_GROUP (pi
->group
),
539 "width", (double) x2
-x1
,
540 "height", (double) y2
-y1
,
542 style
->fill
.pattern
.back
= GO_COLOR_WHITE
;
543 style
->line
.color
= GO_COLOR_BLACK
;
544 style
->line
.width
= 1.;
546 goc_item_invalidate (pi
->group
);
548 draw_margins (state
, x1
, y1
, x2
, y2
);
552 canvas_update (PrinterSetupState
*state
)
554 margin_preview_page_destroy (state
);
555 margin_preview_page_create (state
);
560 cb_spin_activated (UnitInfo
*target
)
562 GOStyle
*style
= go_styled_object_get_style (GO_STYLED_OBJECT (target
->line
));
563 style
->fill
.pattern
.back
= MARGIN_COLOR_ACTIVE
,
564 goc_item_invalidate (target
->line
);
569 cb_spin_deactivated (UnitInfo
*target
)
571 GOStyle
*style
= go_styled_object_get_style (GO_STYLED_OBJECT (target
->line
));
572 style
->fill
.pattern
.back
= MARGIN_COLOR_DEFAULT
,
573 goc_item_invalidate (target
->line
);
579 configure_bounds_header (PrinterSetupState
*state
)
581 double max
= state
->height
- state
->margins
.top
.value
582 - state
->margins
.footer
.value
- state
->margins
.bottom
.value
;
583 gtk_spin_button_set_range (state
->margins
.header
.spin
, 0., max
);
587 configure_bounds_footer (PrinterSetupState
*state
)
589 double max
= state
->height
- state
->margins
.header
.value
590 - state
->margins
.top
.value
- state
->margins
.bottom
.value
;
591 gtk_spin_button_set_range (state
->margins
.footer
.spin
, 0., max
);
595 configure_bounds_bottom (PrinterSetupState
*state
)
597 double max
= state
->height
- state
->margins
.header
.value
598 - state
->margins
.footer
.value
- state
->margins
.top
.value
;
599 gtk_spin_button_set_range (state
->margins
.bottom
.spin
, 0., max
);
603 configure_bounds_top (PrinterSetupState
*state
)
605 double max
= state
->height
- state
->margins
.header
.value
606 - state
->margins
.footer
.value
- state
->margins
.bottom
.value
;
607 gtk_spin_button_set_range (state
->margins
.top
.spin
, 0., max
);
611 configure_bounds_left (PrinterSetupState
*state
)
613 double max
= state
->width
- state
->margins
.right
.value
;
614 gtk_spin_button_set_range (state
->margins
.left
.spin
, 0., max
);
618 configure_bounds_right (PrinterSetupState
*state
)
620 double max
= state
->width
- state
->margins
.left
.value
;
621 gtk_spin_button_set_range (state
->margins
.right
.spin
, 0., max
);
625 value_changed_header_cb (gpointer user_data
)
627 UnitInfo
*target
= user_data
;
629 target
->value
= gtk_spin_button_get_value (target
->spin
);
631 configure_bounds_top (target
->state
);
632 configure_bounds_bottom (target
->state
);
633 configure_bounds_footer (target
->state
);
635 draw_margin_header (target
);
639 value_changed_footer_cb (gpointer user_data
)
641 UnitInfo
*target
= user_data
;
643 target
->value
= gtk_spin_button_get_value (target
->spin
);
645 configure_bounds_top (target
->state
);
646 configure_bounds_bottom (target
->state
);
647 configure_bounds_header (target
->state
);
649 draw_margin_footer (target
);
653 value_changed_top_cb (gpointer user_data
)
655 UnitInfo
*target
= user_data
;
657 target
->value
= gtk_spin_button_get_value (target
->spin
);
659 configure_bounds_header (target
->state
);
660 configure_bounds_bottom (target
->state
);
661 configure_bounds_footer (target
->state
);
663 draw_margin_top (target
);
664 draw_margin_header (&target
->state
->margins
.header
);
669 value_changed_bottom_cb (gpointer user_data
)
671 UnitInfo
*target
= user_data
;
673 target
->value
= gtk_spin_button_get_value (target
->spin
);
675 configure_bounds_header (target
->state
);
676 configure_bounds_top (target
->state
);
677 configure_bounds_footer (target
->state
);
679 draw_margin_bottom (target
);
680 draw_margin_footer (&target
->state
->margins
.footer
);
684 value_changed_left_cb (gpointer user_data
)
686 UnitInfo
*target
= user_data
;
688 target
->value
= gtk_spin_button_get_value (target
->spin
);
690 configure_bounds_right (target
->state
);
692 draw_margin_left (target
);
696 value_changed_right_cb (gpointer user_data
)
698 UnitInfo
*target
= user_data
;
700 target
->value
= gtk_spin_button_get_value (target
->spin
);
702 configure_bounds_left (target
->state
);
704 draw_margin_right (target
);
708 margin_spin_configure (UnitInfo
*target
, PrinterSetupState
*state
,
709 const char *spin_name
,
710 void (*value_changed_cb
) (gpointer user_data
))
713 target
->pi
= &state
->preview
;
714 target
->spin
= GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state
->gui
, spin_name
));
715 target
->state
= state
;
716 gtk_spin_button_set_update_policy (target
->spin
, GTK_UPDATE_IF_VALID
);
717 g_signal_connect_swapped (G_OBJECT (target
->spin
),
719 G_CALLBACK (value_changed_cb
), target
);
720 g_signal_connect_swapped (G_OBJECT (target
->spin
),
722 G_CALLBACK (cb_spin_activated
), target
);
723 g_signal_connect_swapped (G_OBJECT (target
->spin
),
725 G_CALLBACK (cb_spin_deactivated
), target
);
729 cb_unit_selector_changed (G_GNUC_UNUSED GtkComboBox
*widget
,
730 PrinterSetupState
*state
)
735 g_return_if_fail (state
!= NULL
);
737 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (state
->unit_selector
), &iter
)) {
738 gtk_tree_model_get (state
->unit_model
, &iter
, 1, &unit
, -1);
740 do_fetch_margins (state
);
741 state
->display_unit
= unit
;
742 do_update_page (state
);
747 unit_sort_func (GtkTreeModel
*model
,
748 GtkTreeIter
*a
, GtkTreeIter
*b
,
749 G_GNUC_UNUSED gpointer user_data
)
755 gtk_tree_model_get (model
, a
, 0, &str_a
, -1);
756 gtk_tree_model_get (model
, b
, 0, &str_b
, -1);
758 result
= g_utf8_collate (str_a
, str_b
);
767 * Header and footer are stored with Excel semantics, but displayed with
768 * more natural semantics. In Excel, both top margin and header are measured
769 * from top of sheet. The Gnumeric user interface presents header as the
770 * band between top margin and the print area. Bottom margin and footer are
771 * handled likewise. See illustration at top of src/print.c
774 do_setup_margin (PrinterSetupState
*state
)
776 GtkWidget
*grid
, *container
;
777 MarginPreviewPageAvailableSize margin_available_size
;
780 GtkListStore
*list_store
;
783 GtkCellRenderer
*text_renderer
;
785 list_store
= gtk_list_store_new (2, G_TYPE_STRING
, G_TYPE_INT
);
787 gtk_list_store_append (list_store
, &iter
);
788 gtk_list_store_set (list_store
, &iter
, 0, (_("points")), 1, GTK_UNIT_POINTS
, -1);
789 if (GTK_UNIT_POINTS
== state
->display_unit
)
791 gtk_list_store_append (list_store
, &iter
);
792 gtk_list_store_set (list_store
, &iter
, 0, (_("inches")), 1, GTK_UNIT_INCH
, -1);
793 if (GTK_UNIT_INCH
== state
->display_unit
)
795 gtk_list_store_append (list_store
, &iter
);
796 gtk_list_store_set (list_store
, &iter
, 0, (_("mm")), 1, GTK_UNIT_MM
, -1);
797 if (GTK_UNIT_MM
== state
->display_unit
)
800 gtk_tree_sortable_set_default_sort_func
801 (GTK_TREE_SORTABLE (list_store
),
802 unit_sort_func
, NULL
, NULL
);
803 gtk_tree_sortable_set_sort_column_id
804 (GTK_TREE_SORTABLE (list_store
),
805 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID
,
808 state
->unit_selector
= gtk_combo_box_new_with_model (GTK_TREE_MODEL (list_store
));
809 state
->unit_model
= GTK_TREE_MODEL (list_store
);
810 text_renderer
= gtk_cell_renderer_text_new ();
811 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(state
->unit_selector
),
812 text_renderer
, TRUE
);
813 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(state
->unit_selector
),
814 text_renderer
, "text", 0);
816 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (state
->unit_selector
), ¤t
);
818 grid
= go_gtk_builder_get_widget (state
->gui
, "paper-selector-grid");
819 gtk_widget_set_hexpand (state
->unit_selector
, TRUE
);
820 gtk_grid_attach (GTK_GRID (grid
), state
->unit_selector
, 3, 8, 1, 1);
822 g_signal_connect (G_OBJECT (state
->unit_selector
), "changed",
823 G_CALLBACK (cb_unit_selector_changed
), state
);
824 gtk_widget_show (state
->unit_selector
);
826 margin_preview_page_available_size (state
, &margin_available_size
);
828 g_return_if_fail (state
&& state
->pi
);
830 state
->preview
.canvas
= GTK_WIDGET (g_object_new (GOC_TYPE_CANVAS
, NULL
));
831 gtk_widget_set_size_request (state
->preview
.canvas
, margin_available_size
.width
, margin_available_size
.height
);
832 gtk_widget_show (state
->preview
.canvas
);
834 margin_spin_configure (&state
->margins
.header
, state
, "spin-header",
835 value_changed_header_cb
);
836 margin_spin_configure (&state
->margins
.footer
, state
, "spin-footer",
837 value_changed_footer_cb
);
838 margin_spin_configure (&state
->margins
.top
, state
, "spin-top",
839 value_changed_top_cb
);
840 margin_spin_configure (&state
->margins
.bottom
, state
, "spin-bottom",
841 value_changed_bottom_cb
);
842 margin_spin_configure (&state
->margins
.left
, state
, "spin-left",
843 value_changed_left_cb
);
844 margin_spin_configure (&state
->margins
.right
, state
, "spin-right",
845 value_changed_right_cb
);
847 state
->check_center_h
= go_gtk_builder_get_widget (state
->gui
,
849 state
->check_center_v
= go_gtk_builder_get_widget (state
->gui
,
851 gtk_toggle_button_set_active (
852 GTK_TOGGLE_BUTTON (state
->check_center_v
),
853 state
->pi
->center_vertically
== 1);
854 gtk_toggle_button_set_active (
855 GTK_TOGGLE_BUTTON (state
->check_center_h
),
856 state
->pi
->center_horizontally
== 1);
858 container
= go_gtk_builder_get_widget (state
->gui
,
859 "container-paper-sample");
860 gtk_container_add (GTK_CONTAINER (container
), state
->preview
.canvas
);
864 /* Display the header or footer preview in the print setup dialog.
865 * Use the canvas widget in the HFPreviewInfo struct.
869 display_hf_preview (PrinterSetupState
*state
, gboolean header
)
872 GnmPrintHF
*sample
= NULL
;
873 GnmPrintHFRenderInfo
*hfi
;
876 g_return_if_fail (state
!= NULL
);
878 hfi
= gnm_print_hf_render_info_new ();
882 hfi
->sheet
= state
->sheet
;
885 pi
= state
->pi_header
;
886 sample
= state
->header
;
888 pi
= state
->pi_footer
;
889 sample
= state
->footer
;
892 text
= gnm_print_hf_format_render (sample
->left_format
, hfi
, HF_RENDER_PRINT
);
893 goc_item_set (pi
->left
, "text", text
? text
: "", NULL
);
896 text
= gnm_print_hf_format_render (sample
->middle_format
, hfi
, HF_RENDER_PRINT
);
897 goc_item_set (pi
->middle
, "text", text
? text
: "", NULL
);
900 text
= gnm_print_hf_format_render (sample
->right_format
, hfi
, HF_RENDER_PRINT
);
901 goc_item_set (pi
->right
, "text", text
? text
: "", NULL
);
904 gnm_print_hf_render_info_destroy (hfi
);
908 do_header_customize (PrinterSetupState
*state
)
910 do_hf_customize (TRUE
, state
);
914 do_footer_customize (PrinterSetupState
*state
)
916 do_hf_customize (FALSE
, state
);
920 header_changed (GtkComboBox
*menu
, PrinterSetupState
*state
)
922 GList
*selection
= g_list_nth (gnm_print_hf_formats
,
923 gtk_combo_box_get_active (menu
));
924 GnmPrintHF
*format
= (selection
)? selection
->data
: NULL
;
926 if (format
== NULL
) {
927 do_header_customize (state
);
929 gnm_print_hf_free (state
->header
);
930 state
->header
= gnm_print_hf_copy (format
);
933 display_hf_preview (state
, TRUE
);
937 footer_changed (GtkComboBox
*menu
, PrinterSetupState
*state
)
939 GList
*selection
= g_list_nth (gnm_print_hf_formats
,
940 gtk_combo_box_get_active (menu
));
941 GnmPrintHF
*format
= (selection
)? selection
->data
: NULL
;
943 if (format
== NULL
) {
944 do_footer_customize (state
);
946 gnm_print_hf_free (state
->footer
);
947 state
->footer
= gnm_print_hf_copy (format
);
950 display_hf_preview (state
, FALSE
);
954 create_hf_name (char const *left
, char const *middle
, char const *right
)
958 res
= g_strdup_printf ("%s%s%s%s%s",
959 left
," \xe2\x90\xa3 ", middle
, " \xe2\x90\xa3 ", right
);
966 newstring
= g_strconcat (res
, "\xe2\x90\xa4", this + 1, NULL
);
967 this = newstring
+ (this - res
);
971 this = g_utf8_find_next_char (this, NULL
);
978 append_hf_item (GtkListStore
*store
, GnmPrintHF
*format
, GnmPrintHFRenderInfo
*hfi
)
981 char *left
, *middle
, *right
;
984 left
= gnm_print_hf_format_render (format
->left_format
, hfi
, HF_RENDER_PRINT
);
985 middle
= gnm_print_hf_format_render (format
->middle_format
, hfi
, HF_RENDER_PRINT
);
986 right
= gnm_print_hf_format_render (format
->right_format
, hfi
, HF_RENDER_PRINT
);
988 res
= create_hf_name (left
, middle
, right
);
990 gtk_list_store_append (store
, &iter
);
991 gtk_list_store_set (store
, &iter
,
1003 * Fills one of the GtkCombos for headers or footers with the list
1004 * of existing header/footer formats
1007 fill_hf (PrinterSetupState
*state
, GtkComboBox
*om
, GCallback callback
, gboolean header
)
1010 GnmPrintHFRenderInfo
*hfi
;
1011 GtkListStore
*store
;
1012 GnmPrintHF
*select
= header
? state
->header
: state
->footer
;
1015 hfi
= gnm_print_hf_render_info_new ();
1019 store
= gtk_list_store_new (1, G_TYPE_STRING
);
1020 gtk_combo_box_set_model (om
, GTK_TREE_MODEL (store
));
1021 g_object_unref (store
);
1023 for (i
= 0, l
= gnm_print_hf_formats
; l
; l
= l
->next
, i
++) {
1024 GnmPrintHF
*format
= l
->data
;
1026 if (gnm_print_hf_same (format
, select
))
1029 append_hf_item (store
, format
, hfi
);
1033 g_critical ("Current format is not registered!");
1035 gtk_combo_box_set_active (om
, idx
);
1036 g_signal_connect (G_OBJECT (om
), "changed", callback
, state
);
1038 gnm_print_hf_render_info_destroy (hfi
);
1042 do_setup_hf_menus (PrinterSetupState
*state
)
1044 GtkComboBox
*header
;
1045 GtkComboBox
*footer
;
1047 g_return_if_fail (state
!= NULL
);
1049 header
= GTK_COMBO_BOX (go_gtk_builder_get_widget (state
->gui
, "option-menu-header"));
1050 footer
= GTK_COMBO_BOX (go_gtk_builder_get_widget (state
->gui
, "option-menu-footer"));
1053 gnm_print_hf_register (state
->header
);
1055 gnm_print_hf_register (state
->footer
);
1058 fill_hf (state
, header
, G_CALLBACK (header_changed
), TRUE
);
1060 fill_hf (state
, footer
, G_CALLBACK (footer_changed
), FALSE
);
1063 /************* Header Footer Customization *********** Start *************/
1066 hf_delete_tag_cb (HFCustomizeState
*hf_state
)
1070 focus
= gtk_window_get_focus (GTK_WINDOW (hf_state
->dialog
));
1072 if (GTK_IS_TEXT_VIEW (focus
)) {
1073 GtkTextBuffer
*textbuffer
;
1078 textbuffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (focus
));
1079 tag
= gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (textbuffer
),
1081 gtk_text_buffer_get_selection_bounds (textbuffer
, &start
, &end
);
1083 if (gtk_text_iter_has_tag (&start
, tag
) && !gtk_text_iter_begins_tag (&start
, tag
))
1084 gtk_text_iter_backward_to_tag_toggle (&start
, tag
);
1085 if (gtk_text_iter_has_tag (&end
, tag
) && !gtk_text_iter_toggles_tag (&end
, tag
))
1086 gtk_text_iter_forward_to_tag_toggle (&end
, tag
);
1089 gtk_text_buffer_delete (textbuffer
, &start
, &end
);
1095 hf_insert_hf_stock_tag (HFCustomizeState
*hf_state
, GtkTextBuffer
*buffer
,
1096 HFFieldType type
, const char *options
)
1099 gchar
const *icon_name
;
1101 GtkTextMark
*new_mark
;
1102 HFMarkInfo
*mark_info
;
1106 icon_name
= GTK_STOCK_FILE
;
1109 icon_name
= "folder";
1112 icon_name
= "gnumeric-pagesetup-hf-page";
1114 case HF_FIELD_PAGES
:
1115 icon_name
= "gnumeric-pagesetup-hf-pages";
1118 icon_name
= "gnumeric-pagesetup-hf-date";
1121 icon_name
= "gnumeric-pagesetup-hf-time";
1123 case HF_FIELD_SHEET
:
1124 icon_name
= "gnumeric-pagesetup-hf-sheet";
1127 icon_name
= "gnumeric-pagesetup-hf-cell";
1133 hf_delete_tag_cb (hf_state
);
1135 if (gtk_text_buffer_insert_interactive_at_cursor
1136 (buffer
, "", -1, TRUE
)) {
1137 GtkWidget
*w
= GTK_WIDGET (wbcg_toplevel (hf_state
->printer_setup_state
->wbcg
));
1139 gtk_text_buffer_get_iter_at_mark
1140 (buffer
, &iter
, gtk_text_buffer_get_insert (buffer
));
1142 pix
= go_gtk_widget_render_icon_pixbuf (w
, icon_name
, GTK_ICON_SIZE_BUTTON
);
1143 gtk_text_buffer_insert_pixbuf (buffer
, &iter
, pix
);
1144 g_object_unref (pix
);
1145 gtk_text_iter_backward_char (&iter
);
1146 new_mark
= gtk_text_buffer_create_mark (buffer
, NULL
,
1148 g_object_ref (new_mark
);
1150 mark_info
= g_new0 (HFMarkInfo
, 1);
1151 mark_info
->mark
= new_mark
;
1152 mark_info
->type
= type
;
1153 mark_info
->options
= g_strdup (options
);
1154 hf_state
->marks
= g_list_append (hf_state
->marks
, mark_info
);
1159 hf_insert_hf_tag (HFCustomizeState
*hf_state
, HFFieldType type
,
1160 const char *options
)
1164 focus
= gtk_window_get_focus (GTK_WINDOW (hf_state
->dialog
));
1166 if (GTK_IS_TEXT_VIEW (focus
)) {
1167 GtkTextBuffer
*buffer
=
1168 gtk_text_view_get_buffer (GTK_TEXT_VIEW (focus
));
1169 hf_insert_hf_stock_tag (hf_state
, buffer
, type
, options
);
1176 hf_insert_date_cb (GtkWidget
*widget
, HFCustomizeState
*hf_state
)
1179 hf_insert_hf_tag (hf_state
, HF_FIELD_DATE
,
1180 g_object_get_data (G_OBJECT (widget
), "options"));
1184 hf_insert_custom_date_cb (G_GNUC_UNUSED GtkWidget
*widget
,
1185 HFCustomizeState
*hf_state
)
1189 format
= do_hf_dt_format_customize (TRUE
, hf_state
);
1190 if (format
!= NULL
) {
1191 hf_insert_hf_tag (hf_state
, HF_FIELD_DATE
, format
);
1197 hf_insert_time_cb (GtkWidget
*widget
, HFCustomizeState
*hf_state
)
1199 hf_insert_hf_tag (hf_state
, HF_FIELD_TIME
,
1200 g_object_get_data (G_OBJECT (widget
), "options"));
1204 hf_insert_custom_time_cb (G_GNUC_UNUSED GtkWidget
*widget
,
1205 HFCustomizeState
*hf_state
)
1209 format
= do_hf_dt_format_customize (FALSE
, hf_state
);
1210 if (format
!= NULL
) {
1211 hf_insert_hf_tag (hf_state
, HF_FIELD_TIME
, format
);
1217 hf_insert_cell_cb (GtkWidget
*widget
, HFCustomizeState
*hf_state
)
1219 const char *options
;
1220 options
= g_object_get_data (G_OBJECT (widget
), "options");
1221 if (options
== NULL
)
1223 hf_insert_hf_tag (hf_state
, HF_FIELD_CELL
, options
);
1227 hf_insert_page_cb (HFCustomizeState
*hf_state
)
1229 hf_insert_hf_tag (hf_state
, HF_FIELD_PAGE
, NULL
);
1233 hf_insert_pages_cb (HFCustomizeState
*hf_state
)
1235 hf_insert_hf_tag (hf_state
, HF_FIELD_PAGES
, NULL
);
1239 hf_insert_sheet_cb (HFCustomizeState
*hf_state
)
1241 hf_insert_hf_tag (hf_state
, HF_FIELD_SHEET
, NULL
);
1245 hf_insert_file_cb (HFCustomizeState
*hf_state
)
1247 hf_insert_hf_tag (hf_state
, HF_FIELD_FILE
, NULL
);
1251 hf_insert_path_cb (HFCustomizeState
*hf_state
)
1253 hf_insert_hf_tag (hf_state
, HF_FIELD_PATH
, NULL
);
1257 buffer_delete_range_cb (GtkTextBuffer
*textbuffer
,
1260 HFCustomizeState
*hf_state
)
1264 GList
*l
= hf_state
->marks
;
1266 tag
= gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (textbuffer
),
1268 gtk_text_iter_order (start
, end
);
1270 if (gtk_text_iter_has_tag (start
, tag
) && !gtk_text_iter_begins_tag (start
, tag
))
1271 gtk_text_iter_backward_to_tag_toggle (start
, tag
);
1272 if (gtk_text_iter_has_tag (end
, tag
) && !gtk_text_iter_toggles_tag (end
, tag
))
1273 gtk_text_iter_forward_to_tag_toggle (end
, tag
);
1275 /* Deleting all of our marks from this range */
1277 HFMarkInfo
*info
= l
->data
;
1279 if (gtk_text_mark_get_buffer (info
->mark
) == textbuffer
) {
1280 gtk_text_buffer_get_iter_at_mark (textbuffer
, &iter
, info
->mark
);
1281 if (gtk_text_iter_in_range (&iter
, start
, end
))
1282 gtk_text_buffer_delete_mark (textbuffer
, info
->mark
);
1289 mark_info_compare (HFMarkInfo
*a
, HFMarkInfo
*b
)
1291 GtkTextIter iter_a
, iter_b
;
1292 GtkTextBuffer
*buffer
;
1294 buffer
= gtk_text_mark_get_buffer (a
->mark
);
1295 gtk_text_buffer_get_iter_at_mark (buffer
, &iter_a
, a
->mark
);
1296 gtk_text_buffer_get_iter_at_mark (buffer
, &iter_b
, b
->mark
);
1298 return gtk_text_iter_compare (&iter_a
, &iter_b
);
1302 append_tag_descriptor (GString
* string
, HFFieldType type
, char const *options
)
1322 case HF_FIELD_PAGES
:
1325 case HF_FIELD_SHEET
:
1335 g_string_append (string
, code
);
1337 g_string_append_c (string
, ':');
1338 g_string_append (string
, options
);
1340 g_string_append_c (string
, ']');
1344 text_get (HFCustomizeState
*hf_state
, GtkTextBuffer
*buffer
)
1348 GList
*l
, *sorted_marks
= NULL
;
1352 string
= g_string_new ("");
1354 l
= hf_state
->marks
;
1356 HFMarkInfo
*m
= l
->data
;
1357 if (gtk_text_mark_get_buffer (m
->mark
) == buffer
)
1358 sorted_marks
= g_list_insert_sorted
1359 (sorted_marks
, m
, (GCompareFunc
) mark_info_compare
);
1363 gtk_text_buffer_get_bounds (buffer
, &start
, &end
);
1367 HFMarkInfo
*m
= l
->data
;
1368 GtkTextIter mark_position
;
1370 gtk_text_buffer_get_iter_at_mark (buffer
, &mark_position
, m
->mark
);
1371 text
= gtk_text_buffer_get_text (buffer
, &start
, &mark_position
, FALSE
);
1372 g_string_append (string
, text
);
1374 append_tag_descriptor (string
, m
->type
, m
->options
);
1375 start
= mark_position
;
1378 g_list_free (sorted_marks
);
1379 text
= gtk_text_buffer_get_text (buffer
, &start
, &end
, FALSE
);
1380 g_string_append (string
, text
);
1383 return g_string_free (string
, FALSE
);
1387 hf_customize_apply (HFCustomizeState
*hf_state
)
1389 char *left_format
, *right_format
, *middle_format
;
1391 g_return_if_fail (hf_state
!= NULL
);
1393 left_format
= text_get (hf_state
, hf_state
->left_buffer
);
1394 middle_format
= text_get (hf_state
, hf_state
->middle_buffer
);
1395 right_format
= text_get (hf_state
, hf_state
->right_buffer
);
1397 gnm_print_hf_free (*(hf_state
->hf
));
1398 *(hf_state
->hf
) = gnm_print_hf_new (left_format
, middle_format
, right_format
);
1400 g_free (left_format
);
1401 g_free (middle_format
);
1402 g_free (right_format
);
1404 gnm_print_hf_register (*(hf_state
->hf
));
1405 do_setup_hf_menus (hf_state
->printer_setup_state
);
1406 display_hf_preview (hf_state
->printer_setup_state
, hf_state
->is_header
);
1408 gtk_text_buffer_set_modified (hf_state
->left_buffer
, FALSE
);
1409 gtk_text_buffer_set_modified (hf_state
->middle_buffer
, FALSE
);
1410 gtk_text_buffer_set_modified (hf_state
->right_buffer
, FALSE
);
1412 gtk_widget_set_sensitive (go_gtk_builder_get_widget (hf_state
->gui
, "apply_button"), FALSE
);
1413 gtk_widget_set_sensitive (go_gtk_builder_get_widget (hf_state
->gui
, "ok_button"), FALSE
);
1418 hf_customize_ok (HFCustomizeState
*hf_state
)
1420 hf_customize_apply (hf_state
);
1421 gtk_widget_destroy (hf_state
->dialog
);
1425 cb_hf_changed (GtkBuilder
*gui
)
1427 gtk_widget_set_sensitive (go_gtk_builder_get_widget (gui
, "apply_button"), TRUE
);
1428 gtk_widget_set_sensitive (go_gtk_builder_get_widget (gui
, "ok_button"), TRUE
);
1434 add_named_tags (GtkTextBuffer
*buffer
)
1438 tag
= gtk_text_tag_new (HF_TAG_NAME
);
1442 "underline-set", TRUE
,
1443 "weight", PANGO_WEIGHT_BOLD
,
1445 "stretch", PANGO_STRETCH_CONDENSED
,
1446 "stretch-set", TRUE
,
1449 gtk_text_tag_table_add (gtk_text_buffer_get_tag_table (buffer
), tag
);
1453 check_hf_tag (char const *unknown_tag
, char const *known_tag
, gchar
**options
, gint length
)
1456 char const *closing
= unknown_tag
+ length
;
1458 if (0 != g_ascii_strncasecmp (unknown_tag
, "&[", 2))
1461 len
= strlen (known_tag
);
1462 if (0 != g_ascii_strncasecmp (unknown_tag
, known_tag
, len
))
1465 if (*unknown_tag
== ']')
1467 if (*unknown_tag
!= ':')
1470 len
= closing
- unknown_tag
- 1;
1471 if ((len
> 0) && (options
!= NULL
)) {
1472 *options
= g_strndup (unknown_tag
, len
);
1478 is_known_tag (HFCustomizeState
* hf_state
, GtkTextBuffer
*buffer
, char const *tag
, gint length
)
1480 gchar
*options
= NULL
;
1482 if (check_hf_tag (tag
, "FILE", &options
, length
))
1483 hf_insert_hf_stock_tag (hf_state
, buffer
, HF_FIELD_FILE
, options
);
1484 else if (check_hf_tag (tag
, "PATH", &options
, length
))
1485 hf_insert_hf_stock_tag (hf_state
, buffer
, HF_FIELD_PATH
, options
);
1486 else if (check_hf_tag (tag
, "PAGES", &options
, length
))
1487 hf_insert_hf_stock_tag (hf_state
, buffer
, HF_FIELD_PAGES
, options
);
1488 else if (check_hf_tag (tag
, "PAGE", &options
, length
))
1489 hf_insert_hf_stock_tag (hf_state
, buffer
, HF_FIELD_PAGE
, options
);
1490 else if (check_hf_tag (tag
, "TAB", &options
, length
))
1491 hf_insert_hf_stock_tag (hf_state
, buffer
, HF_FIELD_SHEET
, options
);
1492 else if (check_hf_tag (tag
, "DATE", &options
, length
))
1493 hf_insert_hf_stock_tag (hf_state
, buffer
, HF_FIELD_DATE
, options
);
1494 else if (check_hf_tag (tag
, "TIME", &options
, length
))
1495 hf_insert_hf_stock_tag (hf_state
, buffer
, HF_FIELD_TIME
, options
);
1496 else if (check_hf_tag (tag
, "CELL", &options
, length
))
1497 hf_insert_hf_stock_tag (hf_state
, buffer
, HF_FIELD_CELL
, options
);
1507 add_text_to_buffer (HFCustomizeState
* hf_state
, GtkTextBuffer
*buffer
, char const *text
)
1509 gchar
const *here
= text
, *end
;
1510 gunichar closing
= g_utf8_get_char ("]");
1511 gunichar ambersand
= g_utf8_get_char ("&");
1514 g_return_if_fail (here
!= NULL
);
1517 if (here
[0] == '&' && here
[1] == '[') {
1518 end
= g_utf8_strchr (here
, -1, closing
);
1520 gtk_text_buffer_insert (buffer
, &iter
, here
, -1);
1523 if (!is_known_tag ( hf_state
, buffer
, here
, end
- here
+ 1)) {
1524 gtk_text_buffer_get_end_iter (buffer
, &iter
);
1525 gtk_text_buffer_insert_with_tags_by_name
1526 (buffer
, &iter
, here
, end
- here
+ 1,
1532 end
= g_utf8_strchr (g_utf8_find_next_char (here
, NULL
),
1534 gtk_text_buffer_get_end_iter (buffer
, &iter
);
1536 gtk_text_buffer_insert (buffer
, &iter
, here
, -1);
1539 gtk_text_buffer_insert (buffer
, &iter
, here
, end
- here
);
1545 gtk_text_buffer_set_modified (buffer
, FALSE
);
1549 free_hf_mark_info (HFMarkInfo
*info
)
1552 g_object_unref (info
->mark
);
1553 g_free (info
->options
);
1558 free_hf_state (HFCustomizeState
*hf_state
)
1560 g_return_if_fail (hf_state
!= NULL
);
1562 g_list_free_full (hf_state
->marks
, (GDestroyNotify
) free_hf_mark_info
);
1567 hf_attach_insert_date_menu (GtkMenuToolButton
*button
, HFCustomizeState
* hf_state
)
1569 GtkWidget
*menu
= NULL
;
1570 GtkWidget
*item
= NULL
;
1574 "clicked", G_CALLBACK (hf_insert_date_cb
), hf_state
);
1576 menu
= gtk_menu_new ();
1578 item
= gtk_menu_item_new_with_label (_("Default date format"));
1581 "activate", G_CALLBACK (hf_insert_date_cb
), hf_state
);
1582 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1584 item
= gtk_menu_item_new_with_label (_("Custom date format"));
1587 "activate", G_CALLBACK (hf_insert_custom_date_cb
), hf_state
);
1588 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1590 item
= gtk_separator_menu_item_new ();
1591 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1593 item
= gtk_menu_item_new_with_label (("YYYY/MM/DD"));
1596 "activate", G_CALLBACK (hf_insert_date_cb
), hf_state
);
1597 g_object_set_data_full (G_OBJECT (item
), "options", g_strdup("YYYY/MM/DD"), g_free
);
1598 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1600 gtk_menu_tool_button_set_menu (button
, menu
);
1601 gtk_widget_show_all (menu
);
1605 hf_attach_insert_time_menu (GtkMenuToolButton
*button
, HFCustomizeState
* hf_state
)
1607 GtkWidget
*menu
= NULL
;
1608 GtkWidget
*item
= NULL
;
1612 "clicked", G_CALLBACK (hf_insert_time_cb
), hf_state
);
1614 menu
= gtk_menu_new ();
1616 item
= gtk_menu_item_new_with_label (_("Default time format"));
1619 "activate", G_CALLBACK (hf_insert_time_cb
), hf_state
);
1620 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1622 item
= gtk_menu_item_new_with_label (_("Custom time format"));
1625 "activate", G_CALLBACK (hf_insert_custom_time_cb
), hf_state
);
1626 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1628 item
= gtk_separator_menu_item_new ();
1629 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1631 item
= gtk_menu_item_new_with_label (("HH:MM:SS"));
1634 "activate", G_CALLBACK (hf_insert_time_cb
), hf_state
);
1635 g_object_set_data_full (G_OBJECT (item
), "options", g_strdup("HH:MM:SS"), g_free
);
1636 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1638 gtk_menu_tool_button_set_menu (button
, menu
);
1639 gtk_widget_show_all (menu
);
1643 hf_attach_insert_cell_menu (GtkMenuToolButton
*button
, HFCustomizeState
* hf_state
)
1645 GtkWidget
*menu
= NULL
;
1646 GtkWidget
*item
= NULL
;
1650 "clicked", G_CALLBACK (hf_insert_cell_cb
), hf_state
);
1652 menu
= gtk_menu_new ();
1654 item
= gtk_menu_item_new_with_label (_("A1 (first cell of the page area)"));
1657 "activate", G_CALLBACK (hf_insert_cell_cb
), hf_state
);
1658 g_object_set_data_full (G_OBJECT (item
), "options", g_strdup("A1"), g_free
);
1659 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1661 item
= gtk_menu_item_new_with_label (_("$A$1 (first cell of this worksheet)"));
1664 "activate", G_CALLBACK (hf_insert_cell_cb
), hf_state
);
1665 g_object_set_data_full (G_OBJECT (item
), "options", g_strdup("$A$1"), g_free
);
1666 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1668 item
= gtk_menu_item_new_with_label (_("First Printed Cell Of The Page"));
1671 "activate", G_CALLBACK (hf_insert_cell_cb
), hf_state
);
1672 g_object_set_data_full (G_OBJECT (item
), "options", g_strdup("rep|A1"), g_free
);
1673 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
1675 gtk_menu_tool_button_set_menu (button
, menu
);
1676 gtk_widget_show_all (menu
);
1680 cb_hf_destroyed (GObject
*obj
) {
1681 g_object_set_data (obj
, "gui", NULL
);
1685 * Open up a DIALOG to allow the user to customize the header
1689 do_hf_customize (gboolean header
, PrinterSetupState
*state
)
1692 GtkTextView
*left
, *middle
, *right
;
1693 GtkTextBuffer
*left_buffer
, *middle_buffer
, *right_buffer
;
1696 HFCustomizeState
* hf_state
;
1697 GtkToolButton
*button
;
1699 /* Check if this dialog isn't already created. */
1701 dialog
= state
->customize_header
;
1703 dialog
= state
->customize_footer
;
1705 if (dialog
!= NULL
) {
1706 gdk_window_show (gtk_widget_get_window (dialog
));
1707 gdk_window_raise (gtk_widget_get_window (dialog
));
1711 gui
= gnm_gtk_builder_load ("res:ui/hf-config.ui", NULL
, GO_CMD_CONTEXT (state
->wbcg
));
1715 hf_state
= g_new0 (HFCustomizeState
, 1);
1716 hf_state
->gui
= gui
;
1717 hf_state
->printer_setup_state
= state
;
1718 hf_state
->is_header
= header
;
1720 left
= GTK_TEXT_VIEW (go_gtk_builder_get_widget (gui
, "left-format"));
1721 middle
= GTK_TEXT_VIEW (go_gtk_builder_get_widget (gui
, "middle-format"));
1722 right
= GTK_TEXT_VIEW (go_gtk_builder_get_widget (gui
, "right-format"));
1724 dialog
= go_gtk_builder_get_widget (gui
, "hf-config");
1725 hf_state
->dialog
= dialog
;
1728 hf_state
->hf
= &state
->header
;
1729 state
->customize_header
= dialog
;
1730 gtk_window_set_title (GTK_WINDOW (dialog
), _("Custom header configuration"));
1733 hf_state
->hf
= &state
->footer
;
1734 state
->customize_footer
= dialog
;
1735 gtk_window_set_title (GTK_WINDOW (dialog
), _("Custom footer configuration"));
1738 hf_state
->left_buffer
= left_buffer
= gtk_text_view_get_buffer (left
);
1739 hf_state
->middle_buffer
= middle_buffer
= gtk_text_view_get_buffer (middle
);
1740 hf_state
->right_buffer
= right_buffer
= gtk_text_view_get_buffer (right
);
1742 add_named_tags (left_buffer
);
1743 add_named_tags (middle_buffer
);
1744 add_named_tags (right_buffer
);
1746 add_text_to_buffer (hf_state
, left_buffer
, (*(hf_state
->hf
))->left_format
);
1747 add_text_to_buffer (hf_state
, middle_buffer
, (*(hf_state
->hf
))->middle_format
);
1748 add_text_to_buffer (hf_state
, right_buffer
, (*(hf_state
->hf
))->right_format
);
1750 g_signal_connect (G_OBJECT (left_buffer
), "delete-range",
1751 G_CALLBACK (buffer_delete_range_cb
), hf_state
);
1752 g_signal_connect (G_OBJECT (middle_buffer
), "delete-range",
1753 G_CALLBACK (buffer_delete_range_cb
), hf_state
);
1754 g_signal_connect (G_OBJECT (right_buffer
), "delete-range",
1755 G_CALLBACK (buffer_delete_range_cb
), hf_state
);
1757 g_signal_connect_swapped (G_OBJECT (go_gtk_builder_get_widget (gui
, "apply_button")),
1758 "clicked", G_CALLBACK (hf_customize_apply
), hf_state
);
1759 g_signal_connect_swapped (G_OBJECT (go_gtk_builder_get_widget (gui
, "ok_button")),
1760 "clicked", G_CALLBACK (hf_customize_ok
), hf_state
);
1761 g_signal_connect_swapped
1762 (G_OBJECT (go_gtk_builder_get_widget (gui
, "cancel_button")),
1763 "clicked", G_CALLBACK (gtk_widget_destroy
), dialog
);
1764 gtk_widget_set_sensitive (go_gtk_builder_get_widget (gui
, "apply_button"), FALSE
);
1765 gtk_widget_set_sensitive (go_gtk_builder_get_widget (gui
, "ok_button"), FALSE
);
1768 g_signal_connect (G_OBJECT (dialog
), "destroy",
1769 G_CALLBACK (gtk_widget_destroyed
),
1770 &state
->customize_header
);
1772 g_signal_connect (G_OBJECT (dialog
), "destroy",
1773 G_CALLBACK (gtk_widget_destroyed
),
1774 &state
->customize_footer
);
1777 g_object_set_data_full (G_OBJECT (dialog
),
1778 "hfstate", hf_state
, (GDestroyNotify
) free_hf_state
);
1780 /* Setup bindings to mark when the entries are modified. */
1781 g_signal_connect_swapped (G_OBJECT (left_buffer
),
1782 "modified-changed", G_CALLBACK (cb_hf_changed
), gui
);
1783 g_signal_connect_swapped (G_OBJECT (middle_buffer
),
1784 "modified-changed", G_CALLBACK (cb_hf_changed
), gui
);
1785 g_signal_connect_swapped (G_OBJECT (right_buffer
),
1786 "modified-changed", G_CALLBACK (cb_hf_changed
), gui
);
1788 gnm_init_help_button (go_gtk_builder_get_widget (gui
, "help_button"),
1789 header
? GNUMERIC_HELP_LINK_PRINTER_SETUP_HEADER_CUSTOMIZATION
1790 : GNUMERIC_HELP_LINK_PRINTER_SETUP_FOOTER_CUSTOMIZATION
);
1792 g_signal_connect_swapped
1793 (G_OBJECT (go_gtk_builder_get_widget (gui
, "delete-button")),
1794 "clicked", G_CALLBACK (hf_delete_tag_cb
), hf_state
);
1796 button
= GTK_TOOL_BUTTON (go_gtk_builder_get_widget (gui
, "insert-date-button"));
1797 gtk_tool_button_set_icon_name (button
, "gnumeric-pagesetup-hf-date");
1798 hf_attach_insert_date_menu (GTK_MENU_TOOL_BUTTON (button
), hf_state
);
1800 button
= GTK_TOOL_BUTTON (go_gtk_builder_get_widget (gui
, "insert-page-button"));
1801 gtk_tool_button_set_icon_name (button
, "gnumeric-pagesetup-hf-page");
1802 g_signal_connect_swapped
1804 "clicked", G_CALLBACK (hf_insert_page_cb
), hf_state
);
1806 button
= GTK_TOOL_BUTTON (go_gtk_builder_get_widget (gui
, "insert-pages-button"));
1807 gtk_tool_button_set_icon_name (button
, "gnumeric-pagesetup-hf-pages");
1808 g_signal_connect_swapped
1810 "clicked", G_CALLBACK (hf_insert_pages_cb
), hf_state
);
1812 button
= GTK_TOOL_BUTTON (go_gtk_builder_get_widget (gui
, "insert-sheet-button"));
1813 gtk_tool_button_set_icon_name (button
, "gnumeric-pagesetup-hf-sheet");
1814 g_signal_connect_swapped
1816 "clicked", G_CALLBACK (hf_insert_sheet_cb
), hf_state
);
1818 button
= GTK_TOOL_BUTTON (go_gtk_builder_get_widget (gui
, "insert-time-button"));
1819 gtk_tool_button_set_icon_name (button
, "gnumeric-pagesetup-hf-time");
1820 hf_attach_insert_time_menu (GTK_MENU_TOOL_BUTTON (button
), hf_state
);
1822 g_signal_connect_swapped
1823 (G_OBJECT (go_gtk_builder_get_widget (gui
, "insert-file-button")),
1824 "clicked", G_CALLBACK (hf_insert_file_cb
), hf_state
);
1826 g_signal_connect_swapped
1827 (G_OBJECT (go_gtk_builder_get_widget (gui
, "insert-path-button")),
1828 "clicked", G_CALLBACK (hf_insert_path_cb
), hf_state
);
1830 button
= GTK_TOOL_BUTTON (go_gtk_builder_get_widget (gui
, "insert-cell-button"));
1831 gtk_tool_button_set_icon_name (button
, "gnumeric-pagesetup-hf-cell");
1832 hf_attach_insert_cell_menu (GTK_MENU_TOOL_BUTTON (button
), hf_state
);
1835 /* Let them begin typing into the first entry widget. */
1836 gtk_widget_grab_focus (GTK_WIDGET (left
));
1838 gtk_window_set_transient_for (GTK_WINDOW (dialog
),
1839 GTK_WINDOW (state
->dialog
));
1841 /* The following would cause the dialog to be below the page setup dialog: */
1842 /* go_gtk_window_set_transient (GTK_WINDOW (dialog), GTK_WINDOW (state->dialog)); */
1844 g_object_set_data_full (G_OBJECT (dialog
), "gui", gui
, g_object_unref
);
1845 g_signal_connect (G_OBJECT (dialog
), "destroy", G_CALLBACK (cb_hf_destroyed
), NULL
);
1847 gtk_widget_show_all (dialog
);
1850 /************* Header Footer Customization *********** End *************/
1852 /************* Date/Time Format Customization ******** Start ***********/
1855 hf_dt_customize_ok (HFDTFormatState
*hf_dt_state
)
1857 GOFormat
const *format
=
1858 go_format_sel_get_fmt (GO_FORMAT_SEL (hf_dt_state
->format_sel
));
1859 hf_dt_state
->format_string
= g_strdup (go_format_as_XL (format
));
1863 do_hf_dt_format_customize (gboolean date
, HFCustomizeState
*hf_state
)
1867 GtkWidget
*dialog
, *format_sel
, *grid
;
1868 HFDTFormatState
* hf_dt_state
;
1870 char *result_string
= NULL
;
1872 gui
= gnm_gtk_builder_load ("res:ui/hf-dt-format.ui", NULL
,
1873 GO_CMD_CONTEXT (hf_state
->printer_setup_state
->wbcg
));
1877 hf_dt_state
= g_new0 (HFDTFormatState
, 1);
1878 hf_dt_state
->gui
= gui
;
1879 hf_dt_state
->hf_state
= hf_state
;
1880 hf_dt_state
->format_string
= NULL
;
1882 dialog
= go_gtk_builder_get_widget (gui
, "hf-dt-format");
1883 hf_dt_state
->dialog
= dialog
;
1886 gtk_window_set_title (GTK_WINDOW (dialog
), _("Date format selection"));
1888 gtk_window_set_title (GTK_WINDOW (dialog
), _("Time format selection"));
1891 g_signal_connect_swapped (G_OBJECT (go_gtk_builder_get_widget (gui
, "ok_button")),
1892 "clicked", G_CALLBACK (hf_dt_customize_ok
), hf_dt_state
);
1894 g_object_set_data_full (G_OBJECT (dialog
),
1895 "hfdtstate", hf_dt_state
, (GDestroyNotify
) g_free
);
1897 gnm_init_help_button (go_gtk_builder_get_widget (gui
, "help_button"),
1898 GNUMERIC_HELP_LINK_PRINTER_SETUP_GENERAL
);
1900 grid
= go_gtk_builder_get_widget (gui
, "layout-grid");
1901 if (grid
== NULL
) { /* how can this happen? */
1902 gtk_widget_destroy (dialog
);
1905 hf_dt_state
->format_sel
= format_sel
= go_format_sel_new_full (TRUE
);
1906 go_format_sel_set_style_format
1907 (GO_FORMAT_SEL (format_sel
),
1908 date
? go_format_default_date () : go_format_default_time ());
1910 gtk_widget_show_all (dialog
);
1911 gtk_grid_attach (GTK_GRID (grid
), format_sel
, 0, 1, 2, 1);
1912 gtk_widget_show (format_sel
);
1914 result
= gtk_dialog_run (GTK_DIALOG (dialog
));
1917 case GTK_RESPONSE_OK
:
1918 result_string
= hf_dt_state
->format_string
;
1921 gtk_widget_destroy (dialog
);
1924 gtk_widget_destroy (dialog
);
1925 g_object_unref (hf_dt_state
->gui
);
1926 hf_dt_state
->gui
= NULL
;
1927 return result_string
;
1932 /************* Date/Time Format Customization ******** End *************/
1934 /* header/footer_preview_event
1935 * If the user double clicks on a header/footer preview canvas, we will
1936 * open up the dialog to modify the header or footer.
1937 * They can also do this from the option menu.
1940 header_preview_event (G_GNUC_UNUSED GocCanvas
*canvas
,
1941 GdkEvent
*event
, PrinterSetupState
*state
)
1943 if (event
== NULL
||
1944 event
->type
!= GDK_2BUTTON_PRESS
||
1945 event
->button
.button
!= 1)
1947 do_hf_customize (TRUE
, state
);
1952 footer_preview_event (G_GNUC_UNUSED GocCanvas
*canvas
,
1953 GdkEvent
*event
, PrinterSetupState
*state
)
1955 if (event
== NULL
||
1956 event
->type
!= GDK_2BUTTON_PRESS
||
1957 event
->button
.button
!= 1)
1959 do_hf_customize (FALSE
, state
);
1963 /* create_hf_preview_canvas
1964 * Creates the canvas to do a header or footer preview in the print setup.
1968 create_hf_preview_canvas (PrinterSetupState
*state
, gboolean header
)
1972 PangoFontDescription
*font_desc
;
1974 gdouble width
= HF_PREVIEW_X
;
1975 gdouble height
= HF_PREVIEW_Y
;
1976 gdouble shadow
= HF_PREVIEW_SHADOW
;
1977 gdouble padding
= HF_PREVIEW_PADDING
;
1978 gdouble margin
= HF_PREVIEW_MARGIN
;
1979 gdouble bottom_margin
= height
- margin
;
1982 pi
= g_new (HFPreviewInfo
, 1);
1985 state
->pi_header
= pi
;
1987 state
->pi_footer
= pi
;
1989 pi
->canvas
= GTK_WIDGET (g_object_new (GOC_TYPE_CANVAS
, NULL
));
1991 gostyle
= go_styled_object_get_style (
1992 GO_STYLED_OBJECT (goc_item_new (goc_canvas_get_root (GOC_CANVAS (pi
->canvas
)),
1995 "y", (header
? shadow
: 0.),
1997 "height", height
+ (header
? -shadow
: shadow
),
1999 gostyle
->fill
.pattern
.back
= GO_COLOR_BLACK
;
2000 gostyle
->line
.width
= 0.;
2001 gostyle
->line
.color
= 0;
2003 gostyle
= go_styled_object_get_style (
2004 GO_STYLED_OBJECT (goc_item_new (goc_canvas_get_root (GOC_CANVAS (pi
->canvas
)),
2007 "y", (header
? 1.0: 0.),
2011 gostyle
->fill
.pattern
.back
= GO_COLOR_WHITE
;
2012 gostyle
->line
.width
= 0.;
2013 gostyle
->line
.color
= 0;
2015 style
= gnm_conf_get_printer_decoration_font ();
2016 font_desc
= pango_font_description_new ();
2017 pango_font_description_set_family (font_desc
, gnm_style_get_font_name (style
));
2018 pango_font_description_set_style
2019 (font_desc
, gnm_style_get_font_italic (style
) ?
2020 PANGO_STYLE_ITALIC
: PANGO_STYLE_NORMAL
);
2021 pango_font_description_set_variant (font_desc
, PANGO_VARIANT_NORMAL
);
2022 pango_font_description_set_weight (font_desc
, PANGO_WEIGHT_NORMAL
);
2023 pango_font_description_set_size (font_desc
, 8 * PANGO_SCALE
);
2024 gnm_style_unref (style
);
2026 pi
->left
= goc_item_new (
2027 goc_canvas_get_root (GOC_CANVAS (pi
->canvas
)),
2028 goc_text_get_type (),
2030 "y", header
? margin
: bottom_margin
,
2031 "anchor", header
? GO_ANCHOR_NORTH_WEST
: GO_ANCHOR_SOUTH_WEST
,
2034 gostyle
= go_styled_object_get_style (GO_STYLED_OBJECT (pi
->left
));
2035 go_style_set_font_desc (gostyle
, pango_font_description_copy (font_desc
));
2037 pi
->middle
= goc_item_new (
2038 goc_canvas_get_root (GOC_CANVAS (pi
->canvas
)),
2039 goc_text_get_type (),
2041 "y", header
? margin
: bottom_margin
,
2042 "anchor", header
? GO_ANCHOR_NORTH
: GO_ANCHOR_SOUTH
,
2045 gostyle
= go_styled_object_get_style (GO_STYLED_OBJECT (pi
->left
));
2046 go_style_set_font_desc (gostyle
, pango_font_description_copy (font_desc
));
2048 pi
->right
= goc_item_new (
2049 goc_canvas_get_root (GOC_CANVAS (pi
->canvas
)),
2050 goc_text_get_type (),
2051 "x", width
- padding
,
2052 "y", header
? margin
: bottom_margin
,
2053 "anchor", header
? GO_ANCHOR_NORTH_EAST
: GO_ANCHOR_SOUTH_EAST
,
2056 gostyle
= go_styled_object_get_style (GO_STYLED_OBJECT (pi
->left
));
2057 go_style_set_font_desc (gostyle
, pango_font_description_copy (font_desc
));
2059 pango_font_description_free (font_desc
);
2061 gtk_widget_show_all (pi
->canvas
);
2064 g_signal_connect (G_OBJECT (pi
->canvas
),
2066 G_CALLBACK (header_preview_event
), state
);
2067 wid
= go_gtk_builder_get_widget (state
->gui
, "container-header-sample");
2069 g_signal_connect (G_OBJECT (pi
->canvas
),
2071 G_CALLBACK (footer_preview_event
), state
);
2072 wid
= go_gtk_builder_get_widget (state
->gui
, "container-footer-sample");
2074 gtk_widget_set_size_request (pi
->canvas
, width
+ shadow
+ 1, height
+ (header
? 1: shadow
));
2076 gtk_container_add (GTK_CONTAINER (wid
), GTK_WIDGET (pi
->canvas
));
2080 * Setup the widgets for the header and footer tab.
2082 * Creates the two preview canvas's for the header and footer.
2085 do_setup_hf (PrinterSetupState
*state
)
2087 GtkComboBox
*header
;
2088 GtkComboBox
*footer
;
2089 GtkCellRenderer
*renderer
;
2092 g_return_if_fail (state
!= NULL
);
2094 header
= GTK_COMBO_BOX (go_gtk_builder_get_widget (state
->gui
, "option-menu-header"));
2095 renderer
= (GtkCellRenderer
*) gtk_cell_renderer_text_new();
2096 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (header
), renderer
, TRUE
);
2097 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (header
), renderer
,
2100 footer
= GTK_COMBO_BOX (go_gtk_builder_get_widget (state
->gui
, "option-menu-footer"));
2101 renderer
= (GtkCellRenderer
*) gtk_cell_renderer_text_new();
2102 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (footer
), renderer
, TRUE
);
2103 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (footer
), renderer
,
2107 state
->header
= gnm_print_hf_copy (state
->pi
->header
? state
->pi
->header
:
2108 gnm_print_hf_formats
->data
);
2109 state
->footer
= gnm_print_hf_copy (state
->pi
->footer
? state
->pi
->footer
:
2110 gnm_print_hf_formats
->data
);
2112 do_setup_hf_menus (state
);
2114 w
= go_gtk_builder_get_widget (state
->gui
, "configure-header-button");
2115 g_signal_connect_swapped (G_OBJECT (w
),
2117 G_CALLBACK (do_header_customize
), state
);
2118 w
= go_gtk_builder_get_widget (state
->gui
, "configure-footer-button");
2119 g_signal_connect_swapped (G_OBJECT (w
),
2121 G_CALLBACK (do_footer_customize
), state
);
2124 create_hf_preview_canvas (state
, TRUE
);
2125 create_hf_preview_canvas (state
, FALSE
);
2127 display_hf_preview (state
, TRUE
);
2128 display_hf_preview (state
, FALSE
);
2133 display_order_icon (GtkToggleButton
*toggle
, PrinterSetupState
*state
)
2135 GtkWidget
*show
, *hide
;
2137 if (gtk_toggle_button_get_active (toggle
)){
2138 show
= state
->icon_rd
;
2139 hide
= state
->icon_dr
;
2141 hide
= state
->icon_rd
;
2142 show
= state
->icon_dr
;
2145 gtk_widget_show (show
);
2146 gtk_widget_hide (hide
);
2150 load_print_area (PrinterSetupState
*state
)
2152 GnmRange
*print_area
;
2154 print_area
= sheet_get_nominal_printarea
2155 (wb_control_cur_sheet
2156 (GNM_WBC (state
->wbcg
)));
2157 if (print_area
!= NULL
)
2158 gnm_expr_entry_load_from_range
2160 wb_control_cur_sheet (GNM_WBC (state
->wbcg
)),
2163 gnm_expr_entry_load_from_text
2164 (state
->area_entry
, "");
2165 g_free (print_area
);
2169 do_setup_error_display (PrinterSetupState
*state
)
2174 } display_types
[] = {
2175 {N_("Print as displayed"), GNM_PRINT_ERRORS_AS_DISPLAYED
},
2176 {N_("Print as spaces"), GNM_PRINT_ERRORS_AS_BLANK
},
2177 {N_("Print as dashes"), GNM_PRINT_ERRORS_AS_DASHES
},
2178 {N_("Print as #N/A"), GNM_PRINT_ERRORS_AS_NA
}
2182 GtkCellRenderer
*cell
;
2183 gint item
= GNM_PRINT_ERRORS_AS_DISPLAYED
;
2186 for (i
= 0; i
< (int)G_N_ELEMENTS (display_types
); i
++) {
2187 gtk_list_store_insert_with_values (state
->error_display
.store
,
2189 0, _(display_types
[i
].label
),
2190 1, display_types
[i
].type
,
2192 if (display_types
[i
].type
== state
->pi
->error_display
)
2195 cell
= gtk_cell_renderer_text_new();
2196 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(state
->error_display
.combo
), cell
, TRUE
);
2197 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(state
->error_display
.combo
),
2198 cell
, "text", 0, NULL
);
2199 if (gtk_tree_model_iter_nth_child
2200 (GTK_TREE_MODEL (state
->error_display
.store
), &iter
, NULL
, item
))
2201 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (state
->error_display
.combo
), &iter
);
2205 do_setup_comment_display (PrinterSetupState
*state
)
2210 } display_types
[] = {
2211 {N_("Do not print"), GNM_PRINT_COMMENTS_NONE
},
2212 {N_("Print in place"), GNM_PRINT_COMMENTS_IN_PLACE
},
2213 {N_("Print at end"), GNM_PRINT_COMMENTS_AT_END
}
2217 GtkCellRenderer
*cell
;
2218 gint item
= GNM_PRINT_COMMENTS_NONE
;
2221 for (i
= 0; i
< (int)G_N_ELEMENTS (display_types
); i
++) {
2222 gtk_list_store_insert_with_values (state
->comment_display
.store
,
2224 0, _(display_types
[i
].label
),
2225 1, display_types
[i
].type
,
2227 if (display_types
[i
].type
== state
->pi
->comment_placement
)
2230 cell
= gtk_cell_renderer_text_new();
2231 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(state
->comment_display
.combo
), cell
, TRUE
);
2232 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(state
->comment_display
.combo
), cell
, "text", 0, NULL
);
2233 if (gtk_tree_model_iter_nth_child
2234 (GTK_TREE_MODEL (state
->comment_display
.store
), &iter
, NULL
, item
))
2235 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (state
->comment_display
.combo
), &iter
);
2237 gtk_widget_set_sensitive (state
->comment_display
.combo
, FALSE
);
2241 do_setup_page_area (PrinterSetupState
*state
)
2243 GtkWidget
*pa_grid
= go_gtk_builder_get_widget (state
->gui
,
2245 GtkWidget
*repeat_grid
= go_gtk_builder_get_widget (state
->gui
,
2248 state
->area_entry
= gnm_expr_entry_new (state
->wbcg
, FALSE
);
2249 gnm_expr_entry_set_flags (state
->area_entry
,
2250 GNM_EE_SHEET_OPTIONAL
,
2251 GNM_EE_SHEET_OPTIONAL
);
2252 gtk_container_add (GTK_CONTAINER (pa_grid
),
2253 GTK_WIDGET (state
->area_entry
));
2254 gtk_widget_set_hexpand (GTK_WIDGET (state
->area_entry
), TRUE
);
2255 gtk_widget_show (GTK_WIDGET (state
->area_entry
));
2257 state
->top_entry
= gnm_expr_entry_new (state
->wbcg
, TRUE
);
2258 gnm_expr_entry_set_flags (state
->top_entry
,
2259 GNM_EE_SINGLE_RANGE
| GNM_EE_FULL_ROW
| GNM_EE_SHEET_OPTIONAL
,
2261 gtk_widget_set_hexpand (GTK_WIDGET (state
->top_entry
), TRUE
);
2262 gtk_grid_attach (GTK_GRID (repeat_grid
),
2263 GTK_WIDGET (state
->top_entry
), 1, 2, 1, 1);
2264 gtk_widget_show (GTK_WIDGET (state
->top_entry
));
2266 state
->left_entry
= gnm_expr_entry_new (state
->wbcg
, TRUE
);
2267 gnm_expr_entry_set_flags (state
->left_entry
,
2268 GNM_EE_SINGLE_RANGE
| GNM_EE_FULL_COL
| GNM_EE_SHEET_OPTIONAL
,
2270 gtk_widget_set_hexpand (GTK_WIDGET (state
->left_entry
), TRUE
);
2271 gtk_grid_attach (GTK_GRID (repeat_grid
),
2272 GTK_WIDGET (state
->left_entry
), 1, 3, 1, 1);
2273 gtk_widget_show (GTK_WIDGET (state
->left_entry
));
2276 gnm_editable_enters (GTK_WINDOW (state
->dialog
),
2277 GTK_WIDGET (gnm_expr_entry_get_entry (state
->area_entry
)));
2278 gnm_editable_enters (GTK_WINDOW (state
->dialog
),
2279 GTK_WIDGET (gnm_expr_entry_get_entry (state
->top_entry
)));
2280 gnm_editable_enters (GTK_WINDOW (state
->dialog
),
2281 GTK_WIDGET (gnm_expr_entry_get_entry (state
->left_entry
)));
2283 gnm_expr_entry_load_from_text (state
->top_entry
,
2284 state
->pi
->repeat_top
);
2285 gnm_expr_entry_load_from_text (state
->left_entry
,
2286 state
->pi
->repeat_left
);
2288 load_print_area (state
);
2292 do_setup_page_info (PrinterSetupState
*state
)
2294 GtkWidget
*gridlines
= go_gtk_builder_get_widget (state
->gui
, "check-grid-lines");
2295 GtkWidget
*onlystyles
= go_gtk_builder_get_widget (state
->gui
, "check-only-styles");
2296 GtkWidget
*bw
= go_gtk_builder_get_widget (state
->gui
, "check-black-white");
2297 GtkWidget
*titles
= go_gtk_builder_get_widget (state
->gui
, "check-print-titles");
2298 GtkWidget
*do_not_print
= go_gtk_builder_get_widget (state
->gui
, "check-do-not-print");
2299 GtkWidget
*order_rd
= go_gtk_builder_get_widget (state
->gui
, "radio-order-right");
2300 GtkWidget
*order_dr
= go_gtk_builder_get_widget (state
->gui
, "radio-order-down");
2301 GtkWidget
*order_grid
= go_gtk_builder_get_widget (state
->gui
, "page-order-grid");
2304 state
->error_display
.combo
= go_gtk_builder_get_widget (state
->gui
, "error-box");
2305 state
->error_display
.store
= GTK_LIST_STORE (gtk_combo_box_get_model
2306 (GTK_COMBO_BOX (state
->error_display
.combo
)));
2307 do_setup_error_display (state
);
2309 state
->comment_display
.combo
= go_gtk_builder_get_widget (state
->gui
, "comments-box");
2310 state
->comment_display
.store
= GTK_LIST_STORE (gtk_combo_box_get_model
2311 (GTK_COMBO_BOX (state
->comment_display
.combo
)));
2312 do_setup_comment_display (state
);
2314 state
->icon_rd
= gtk_image_new_from_resource ("/org/gnumeric/gnumeric/images/right-down.png");
2315 state
->icon_dr
= gtk_image_new_from_resource ("/org/gnumeric/gnumeric/images/down-right.png");
2317 gtk_widget_hide (state
->icon_dr
);
2318 gtk_widget_hide (state
->icon_rd
);
2320 gtk_grid_attach (GTK_GRID (order_grid
), state
->icon_rd
, 1, 0, 1, 2);
2321 gtk_grid_attach (GTK_GRID (order_grid
), state
->icon_dr
, 1, 0, 1, 2);
2323 g_signal_connect (G_OBJECT (order_rd
), "toggled", G_CALLBACK (display_order_icon
), state
);
2325 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gridlines
),
2326 state
->pi
->print_grid_lines
);
2327 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (onlystyles
),
2328 state
->pi
->print_even_if_only_styles
);
2329 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bw
),
2330 state
->pi
->print_black_and_white
);
2331 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (titles
),
2332 state
->pi
->print_titles
);
2333 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (do_not_print
),
2334 state
->pi
->do_not_print
);
2336 order
= state
->pi
->print_across_then_down
? order_rd
: order_dr
;
2337 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (order
), TRUE
);
2338 display_order_icon (GTK_TOGGLE_BUTTON (order_rd
), state
);
2343 do_update_margin (UnitInfo
*margin
, double value
, GtkUnit unit
)
2345 margin
->value
= value
;
2346 gtk_spin_button_set_range (margin
->spin
, 0. , 2. * value
);
2347 gtk_spin_button_set_value (margin
->spin
, value
);
2350 gtk_spin_button_set_digits (margin
->spin
, 1);
2351 gtk_spin_button_set_increments (margin
->spin
, 1., 0.);
2354 gtk_spin_button_set_digits (margin
->spin
, 3);
2355 gtk_spin_button_set_increments (margin
->spin
, 0.125, 0.);
2357 case GTK_UNIT_POINTS
:
2358 gtk_spin_button_set_digits (margin
->spin
, 1);
2359 gtk_spin_button_set_increments (margin
->spin
, 1., 0.);
2361 case GTK_UNIT_PIXEL
:
2367 do_update_page (PrinterSetupState
*state
)
2369 GnmPrintInformation
*pi
= state
->pi
;
2373 double edge_to_below_header
, edge_to_above_footer
;
2380 gtk_label_set_text (GTK_LABEL (go_gtk_builder_get_widget (gui
,
2381 "paper-type-label")),
2382 print_info_get_paper_display_name (pi
));
2383 state
->height
= print_info_get_paper_height (pi
,state
->display_unit
);
2384 state
->width
= print_info_get_paper_width (pi
,state
->display_unit
);
2385 switch (state
->display_unit
) {
2386 case GTK_UNIT_PIXEL
:
2387 format
= _("%.0f pixels wide by %.0f pixels tall");
2389 case GTK_UNIT_POINTS
:
2390 format
= _("%.0f points wide by %.0f points tall");
2393 format
= _("%.1f in wide by %.1f in tall");
2396 format
= _("%.0f mm wide by %.0f mm tall");
2399 format
= _("%.1f wide by %.1f tall");
2402 text
= g_strdup_printf (format
, state
->width
, state
->height
);
2403 gtk_label_set_text (GTK_LABEL (go_gtk_builder_get_widget (gui
,
2404 "paper-size-label")),
2408 print_info_get_margins (state
->pi
,
2411 &edge_to_below_header
,
2412 &edge_to_above_footer
);
2413 scale
= get_conversion_factor (state
->display_unit
);
2414 do_update_margin (&state
->margins
.header
,
2415 (edge_to_below_header
- top
) / scale
,
2416 state
->display_unit
);
2417 do_update_margin (&state
->margins
.footer
,
2418 (edge_to_above_footer
- bottom
) / scale
,
2419 state
->display_unit
);
2420 do_update_margin (&state
->margins
.top
, top
/ scale
,
2421 state
->display_unit
);
2422 do_update_margin (&state
->margins
.bottom
, bottom
/ scale
,
2423 state
->display_unit
);
2424 do_update_margin (&state
->margins
.left
, left
/ scale
,
2425 state
->display_unit
);
2426 do_update_margin (&state
->margins
.right
, right
/ scale
,
2427 state
->display_unit
);
2428 configure_bounds_top (state
);
2429 configure_bounds_header (state
);
2430 configure_bounds_left (state
);
2431 configure_bounds_right (state
);
2432 configure_bounds_footer (state
);
2433 configure_bounds_bottom (state
);
2435 canvas_update (state
);
2437 switch (print_info_get_paper_orientation (state
->pi
)) {
2438 case GTK_PAGE_ORIENTATION_PORTRAIT
:
2439 gtk_toggle_button_set_active
2440 (GTK_TOGGLE_BUTTON (state
->portrait_radio
), TRUE
);
2442 case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT
:
2443 gtk_toggle_button_set_active
2444 (GTK_TOGGLE_BUTTON (state
->rev_portrait_radio
), TRUE
);
2446 case GTK_PAGE_ORIENTATION_LANDSCAPE
:
2447 gtk_toggle_button_set_active
2448 (GTK_TOGGLE_BUTTON (state
->landscape_radio
), TRUE
);
2451 gtk_toggle_button_set_active
2452 (GTK_TOGGLE_BUTTON (state
->rev_landscape_radio
), TRUE
);
2459 orientation_changed_cb (PrinterSetupState
*state
)
2461 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state
->portrait_radio
)))
2462 print_info_set_paper_orientation (state
->pi
, GTK_PAGE_ORIENTATION_PORTRAIT
);
2463 else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state
->rev_portrait_radio
)))
2464 print_info_set_paper_orientation (state
->pi
, GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT
);
2465 else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state
->landscape_radio
)))
2466 print_info_set_paper_orientation (state
->pi
, GTK_PAGE_ORIENTATION_LANDSCAPE
);
2468 print_info_set_paper_orientation (state
->pi
, GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE
);
2469 do_update_page (state
);
2473 do_setup_page (PrinterSetupState
*state
)
2479 g_signal_connect_swapped (G_OBJECT (go_gtk_builder_get_widget (gui
, "paper-button")),
2481 G_CALLBACK (dialog_gtk_printer_setup_cb
), state
);
2483 state
->portrait_radio
= go_gtk_builder_get_widget (gui
, "portrait-button");
2484 state
->landscape_radio
= go_gtk_builder_get_widget (gui
, "landscape-button");
2485 state
->rev_portrait_radio
= go_gtk_builder_get_widget (gui
, "r-portrait-button");
2486 state
->rev_landscape_radio
= go_gtk_builder_get_widget (gui
, "r-landscape-button");
2488 g_signal_connect_swapped (G_OBJECT (state
->portrait_radio
), "toggled",
2489 G_CALLBACK (orientation_changed_cb
), state
);
2490 g_signal_connect_swapped (G_OBJECT (state
->rev_portrait_radio
), "toggled",
2491 G_CALLBACK (orientation_changed_cb
), state
);
2492 g_signal_connect_swapped (G_OBJECT (state
->landscape_radio
), "toggled",
2493 G_CALLBACK (orientation_changed_cb
), state
);
2495 do_setup_margin (state
);
2497 do_update_page (state
);
2503 scaling_percent_changed (GtkToggleButton
*toggle
, PrinterSetupState
*state
)
2505 gboolean scale_percent
= gtk_toggle_button_get_active (toggle
);
2507 gtk_widget_set_sensitive (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "scale-percent-spin")), scale_percent
);
2508 gtk_widget_set_sensitive (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "scale-percent-label")), scale_percent
);
2512 scaling_fit_to_h_changed (GtkToggleButton
*toggle
, PrinterSetupState
*state
)
2514 gboolean scale_fit_to_h
= gtk_toggle_button_get_active (toggle
);
2515 gtk_widget_set_sensitive
2516 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "scale-h-spin")),
2518 gtk_widget_set_sensitive
2519 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "fit-h-check-label")),
2524 scaling_fit_to_v_changed (GtkToggleButton
*toggle
, PrinterSetupState
*state
)
2526 gboolean scale_fit_to_v
= gtk_toggle_button_get_active (toggle
);
2527 gtk_widget_set_sensitive
2528 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "scale-v-spin")),
2530 gtk_widget_set_sensitive
2531 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "fit-v-check-label")),
2536 scaling_fit_to_changed (GtkToggleButton
*toggle
, PrinterSetupState
*state
)
2538 gboolean scale_fit_to
= gtk_toggle_button_get_active (toggle
);
2541 scaling_fit_to_h_changed (GTK_TOGGLE_BUTTON
2542 (go_gtk_builder_get_widget (state
->gui
, "fit-h-check")), state
);
2543 scaling_fit_to_v_changed (GTK_TOGGLE_BUTTON
2544 (go_gtk_builder_get_widget (state
->gui
, "fit-v-check")), state
);
2546 gtk_widget_set_sensitive
2547 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "scale-v-spin")), FALSE
);
2548 gtk_widget_set_sensitive
2549 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "fit-v-check-label")), FALSE
);
2550 gtk_widget_set_sensitive
2551 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "scale-h-spin")), FALSE
);
2552 gtk_widget_set_sensitive
2553 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "fit-h-check-label")), FALSE
);
2555 gtk_widget_set_sensitive
2556 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "fit-h-check")), scale_fit_to
);
2557 gtk_widget_set_sensitive
2558 (GTK_WIDGET (go_gtk_builder_get_widget (state
->gui
, "fit-v-check")), scale_fit_to
);
2562 do_setup_scale (PrinterSetupState
*state
)
2564 GnmPrintInformation
*pi
= state
->pi
;
2565 GtkWidget
*scale_percent_spin
, *scale_width_spin
, *scale_height_spin
;
2570 state
->scale_percent_radio
= go_gtk_builder_get_widget (gui
, "scale-percent-radio");
2571 state
->scale_fit_to_radio
= go_gtk_builder_get_widget (gui
, "scale-fit-to-radio");
2572 state
->scale_no_radio
= go_gtk_builder_get_widget (gui
, "scale-no-radio");
2574 g_signal_connect (G_OBJECT (state
->scale_percent_radio
), "toggled",
2575 G_CALLBACK (scaling_percent_changed
), state
);
2576 g_signal_connect (G_OBJECT (state
->scale_fit_to_radio
), "toggled",
2577 G_CALLBACK (scaling_fit_to_changed
), state
);
2578 g_signal_connect (G_OBJECT (go_gtk_builder_get_widget (state
->gui
, "fit-h-check")),
2579 "toggled", G_CALLBACK (scaling_fit_to_h_changed
), state
);
2580 g_signal_connect (G_OBJECT (go_gtk_builder_get_widget (state
->gui
, "fit-v-check")),
2581 "toggled", G_CALLBACK (scaling_fit_to_v_changed
), state
);
2583 scaling_percent_changed (GTK_TOGGLE_BUTTON (state
->scale_percent_radio
), state
);
2584 scaling_fit_to_changed (GTK_TOGGLE_BUTTON (state
->scale_fit_to_radio
), state
);
2587 if (pi
->scaling
.type
== PRINT_SCALE_PERCENTAGE
) {
2588 if (pi
->scaling
.percentage
.x
== 100.)
2589 gtk_toggle_button_set_active
2590 (GTK_TOGGLE_BUTTON (state
->scale_no_radio
), TRUE
);
2592 gtk_toggle_button_set_active
2593 (GTK_TOGGLE_BUTTON (state
->scale_percent_radio
), TRUE
);
2595 gtk_toggle_button_set_active
2596 (GTK_TOGGLE_BUTTON (state
->scale_fit_to_radio
), TRUE
);
2599 scale_percent_spin
= go_gtk_builder_get_widget (gui
, "scale-percent-spin");
2600 gtk_spin_button_set_value (
2601 GTK_SPIN_BUTTON (scale_percent_spin
), pi
->scaling
.percentage
.x
);
2602 gnm_editable_enters (GTK_WINDOW (state
->dialog
),
2603 GTK_WIDGET (scale_percent_spin
));
2605 scale_width_spin
= go_gtk_builder_get_widget (gui
, "scale-h-spin");
2606 gtk_spin_button_set_value (
2607 GTK_SPIN_BUTTON (scale_width_spin
), pi
->scaling
.dim
.cols
);
2608 gtk_toggle_button_set_active
2609 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state
->gui
, "fit-h-check")),
2610 pi
->scaling
.dim
.cols
> 0);
2611 gnm_editable_enters (GTK_WINDOW (state
->dialog
),
2612 GTK_WIDGET (scale_width_spin
));
2614 scale_height_spin
= go_gtk_builder_get_widget (gui
, "scale-v-spin");
2615 gtk_spin_button_set_value (
2616 GTK_SPIN_BUTTON (scale_height_spin
), pi
->scaling
.dim
.rows
);
2617 gtk_toggle_button_set_active
2618 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state
->gui
, "fit-v-check")),
2619 pi
->scaling
.dim
.rows
> 0);
2620 gnm_editable_enters (GTK_WINDOW (state
->dialog
),
2621 GTK_WIDGET (scale_height_spin
));
2626 print_setup_get_sheet (PrinterSetupState
*state
)
2628 GtkWidget
*w
= go_gtk_builder_get_widget (state
->gui
, "apply-to-all");
2629 gboolean apply_all_sheets
= gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w
));
2631 gnm_conf_set_printsetup_all_sheets (apply_all_sheets
);
2633 if (apply_all_sheets
)
2635 return workbook_sheet_by_index (state
->sheet
->workbook
,
2636 gtk_combo_box_get_active (GTK_COMBO_BOX
2637 (state
->sheet_selector
)));
2641 cb_do_print_preview (PrinterSetupState
*state
)
2643 GnmPrintInformation
*old_pi
;
2644 double width
, height
;
2645 GogGraph
*graph
= NULL
;
2647 fetch_settings (state
);
2648 old_pi
= state
->sheet
->print_info
;
2649 state
->sheet
->print_info
= state
->pi
;
2650 if (state
->sheet
->sheet_type
== GNM_SHEET_OBJECT
) {
2651 graph
= GOG_GRAPH (sheet_object_graph_get_gog (GNM_SO (state
->sheet
->sheet_objects
->data
)));
2653 double top
, bottom
, left
, right
, edge_to_below_header
, edge_to_above_footer
, w
, h
;
2654 gog_graph_get_size (graph
, &width
, &height
);
2655 w
= print_info_get_paper_width (state
->pi
, GTK_UNIT_POINTS
);
2656 h
= print_info_get_paper_height (state
->pi
, GTK_UNIT_POINTS
);
2657 print_info_get_margins (state
->pi
, &top
, &bottom
, &left
, &right
, &edge_to_below_header
, &edge_to_above_footer
);
2659 h
-= top
+ bottom
+ edge_to_above_footer
+ edge_to_below_header
;
2660 gog_graph_set_size (graph
, w
, h
);
2663 gnm_print_sheet (GNM_WBC (state
->wbcg
),
2664 state
->sheet
, TRUE
, GNM_PRINT_ACTIVE_SHEET
, NULL
);
2666 gog_graph_set_size (graph
, width
, height
);
2667 state
->sheet
->print_info
= old_pi
;
2671 cb_do_print_cancel (PrinterSetupState
*state
)
2673 gtk_widget_destroy (state
->dialog
);
2677 cb_do_print_ok (PrinterSetupState
*state
)
2679 fetch_settings (state
);
2680 if (gtk_toggle_button_get_active (
2682 go_gtk_builder_get_widget (state
->gui
,
2683 "is_default_check")))) {
2684 gnm_print_info_save (state
->pi
);
2686 cmd_print_setup (GNM_WBC (state
->wbcg
),
2687 print_setup_get_sheet (state
), state
->pi
);
2688 gtk_widget_destroy (state
->dialog
);
2692 cb_do_print (PrinterSetupState
*state
)
2694 Sheet
*sheet
= state
->sheet
;
2695 WorkbookControl
*wbc
= GNM_WBC (state
->wbcg
);
2697 cb_do_print_ok (state
);
2698 gnm_print_sheet (wbc
, sheet
, FALSE
, GNM_PRINT_SAVED_INFO
, NULL
);
2702 cb_do_print_destroy (PrinterSetupState
*state
)
2704 if (state
->customize_header
)
2705 gtk_widget_destroy (state
->customize_header
);
2707 if (state
->customize_footer
)
2708 gtk_widget_destroy (state
->customize_footer
);
2710 g_object_unref (state
->gui
);
2712 gnm_print_hf_free (state
->header
);
2713 gnm_print_hf_free (state
->footer
);
2714 gnm_print_info_free (state
->pi
);
2715 g_free (state
->pi_header
);
2716 g_free (state
->pi_footer
);
2717 g_object_unref (state
->unit_model
);
2722 cb_do_sheet_selector_toggled (GtkToggleButton
*togglebutton
,
2723 PrinterSetupState
*state
)
2725 gboolean all_sheets
= gtk_toggle_button_get_active (togglebutton
);
2727 gtk_widget_set_sensitive (state
->sheet_selector
, !all_sheets
);
2731 do_setup_sheet_selector (PrinterSetupState
*state
)
2733 GtkWidget
*grid
, *w
;
2734 int i
, n
, n_this
= 0;
2736 g_return_if_fail (state
!= NULL
);
2737 g_return_if_fail (state
->sheet
!= NULL
);
2739 grid
= go_gtk_builder_get_widget (state
->gui
, "sheet-grid");
2740 state
->sheet_selector
= gtk_combo_box_text_new ();
2741 n
= workbook_sheet_count (state
->sheet
->workbook
);
2742 for (i
= 0 ; i
< n
; i
++) {
2743 Sheet
* a_sheet
= workbook_sheet_by_index (state
->sheet
->workbook
, i
);
2744 if (a_sheet
== state
->sheet
)
2746 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (state
->sheet_selector
),
2747 a_sheet
->name_unquoted
);
2749 gtk_combo_box_set_active (GTK_COMBO_BOX (state
->sheet_selector
), n_this
);
2750 gtk_widget_set_hexpand (state
->sheet_selector
, TRUE
);
2751 gtk_grid_attach (GTK_GRID (grid
), state
->sheet_selector
, 1, 1, 1, 1);
2752 w
= go_gtk_builder_get_widget (state
->gui
, "apply-to-all");
2753 g_signal_connect (G_OBJECT (w
),
2755 G_CALLBACK (cb_do_sheet_selector_toggled
), state
);
2756 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w
),
2757 gnm_conf_get_printsetup_all_sheets ());
2758 cb_do_sheet_selector_toggled (GTK_TOGGLE_BUTTON (w
), state
);
2759 w
= go_gtk_builder_get_widget (state
->gui
, "apply-to-selected");
2760 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w
),
2761 !gnm_conf_get_printsetup_all_sheets ());
2762 gtk_widget_show_all (grid
);
2766 do_setup_main_dialog (PrinterSetupState
*state
)
2770 g_return_if_fail (state
!= NULL
);
2771 g_return_if_fail (state
->sheet
!= NULL
);
2772 g_return_if_fail (state
->wbcg
!= NULL
);
2774 state
->dialog
= go_gtk_builder_get_widget (state
->gui
, "print-setup");
2776 w
= go_gtk_builder_get_widget (state
->gui
, "ok");
2777 g_signal_connect_swapped (G_OBJECT (w
),
2779 G_CALLBACK (cb_do_print_ok
), state
);
2780 w
= go_gtk_builder_get_widget (state
->gui
, "print");
2781 g_signal_connect_swapped (G_OBJECT (w
),
2783 G_CALLBACK (cb_do_print
), state
);
2784 w
= go_gtk_builder_get_widget (state
->gui
, "preview");
2785 g_signal_connect_swapped (G_OBJECT (w
),
2787 G_CALLBACK (cb_do_print_preview
), state
);
2788 w
= go_gtk_builder_get_widget (state
->gui
, "cancel");
2789 g_signal_connect_swapped (G_OBJECT (w
),
2791 G_CALLBACK (cb_do_print_cancel
), state
);
2793 w
= go_gtk_builder_get_widget (state
->gui
, "print-setup-notebook");
2794 gtk_notebook_set_current_page (GTK_NOTEBOOK (w
), 0);
2796 g_object_set_data_full (G_OBJECT (state
->dialog
),
2797 "state", state
, (GDestroyNotify
) cb_do_print_destroy
);
2798 wbc_gtk_attach_guru (state
->wbcg
, state
->dialog
);
2801 static PrinterSetupState
*
2802 printer_setup_state_new (WBCGtk
*wbcg
, Sheet
*sheet
)
2804 PrinterSetupState
*state
;
2807 gui
= gnm_gtk_builder_load ("res:ui/print.ui", NULL
, GO_CMD_CONTEXT (wbcg
));
2811 state
= g_new0 (PrinterSetupState
, 1);
2813 state
->sheet
= sheet
;
2815 state
->pi
= gnm_print_info_dup (sheet
->print_info
);
2816 state
->display_unit
= state
->pi
->desired_display
.top
;
2817 state
->customize_header
= NULL
;
2818 state
->customize_footer
= NULL
;
2820 do_setup_main_dialog (state
);
2821 do_setup_sheet_selector (state
);
2822 do_setup_hf (state
);
2823 do_setup_page_area (state
);
2824 do_setup_page_info (state
);
2825 do_setup_page (state
);
2826 do_setup_scale (state
);
2832 do_fetch_page (PrinterSetupState
*state
)
2834 state
->pi
->center_horizontally
= gtk_toggle_button_get_active
2835 (GTK_TOGGLE_BUTTON (state
->check_center_h
));
2836 state
->pi
->center_vertically
= gtk_toggle_button_get_active
2837 (GTK_TOGGLE_BUTTON (state
->check_center_v
));
2841 do_fetch_unit (PrinterSetupState
*state
)
2843 if (state
->display_unit
!= state
->pi
->desired_display
.top
) {
2844 state
->pi
->desired_display
.top
= state
->display_unit
;
2845 state
->pi
->desired_display
.bottom
= state
->display_unit
;
2846 state
->pi
->desired_display
.header
= state
->display_unit
;
2847 state
->pi
->desired_display
.footer
= state
->display_unit
;
2848 state
->pi
->desired_display
.left
= state
->display_unit
;
2849 state
->pi
->desired_display
.right
= state
->display_unit
;
2854 do_fetch_scale (PrinterSetupState
*state
)
2857 GtkBuilder
*gui
= state
->gui
;
2859 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (state
->scale_no_radio
))) {
2860 state
->pi
->scaling
.percentage
.x
= state
->pi
->scaling
.percentage
.y
= 100.;
2861 state
->pi
->scaling
.type
= PRINT_SCALE_PERCENTAGE
;
2863 w
= go_gtk_builder_get_widget (gui
, "scale-percent-spin");
2864 state
->pi
->scaling
.percentage
.x
= state
->pi
->scaling
.percentage
.y
2865 = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w
));
2866 state
->pi
->scaling
.type
=
2867 ((gtk_toggle_button_get_active
2868 (GTK_TOGGLE_BUTTON (state
->scale_percent_radio
))) ?
2869 PRINT_SCALE_PERCENTAGE
: PRINT_SCALE_FIT_PAGES
);
2871 w
= go_gtk_builder_get_widget (gui
, "fit-h-check");
2872 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w
)))
2873 state
->pi
->scaling
.dim
.cols
= 0;
2875 w
= go_gtk_builder_get_widget (gui
, "scale-h-spin");
2876 state
->pi
->scaling
.dim
.cols
=
2877 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w
));
2880 w
= go_gtk_builder_get_widget (gui
, "fit-v-check");
2881 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w
)))
2882 state
->pi
->scaling
.dim
.rows
= 0;
2884 w
= go_gtk_builder_get_widget (gui
, "scale-v-spin");
2885 state
->pi
->scaling
.dim
.rows
=
2886 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w
));
2891 * Header and footer are stored with Excel semantics, but displayed with
2892 * more natural semantics. In Excel, both top margin and header are measured
2893 * from top of sheet. See illustration at start of src/print.c. The Gnumeric
2894 * user interface presents header as the band between top margin and the
2895 * print area. Bottom margin and footer are handled likewise.
2898 do_fetch_margins (PrinterSetupState
*state
)
2900 double header
, footer
, top
, bottom
, left
, right
;
2901 GtkPageSetup
*ps
= gnm_print_info_get_page_setup (state
->pi
);
2902 double factor
= get_conversion_factor (state
->display_unit
);
2904 header
= state
->margins
.header
.value
;
2905 footer
= state
->margins
.footer
.value
;
2906 top
= state
->margins
.top
.value
;
2907 bottom
= state
->margins
.bottom
.value
;
2908 left
= state
->margins
.left
.value
;
2909 right
= state
->margins
.right
.value
;
2911 gtk_page_setup_set_top_margin (ps
, top
, state
->display_unit
);
2912 gtk_page_setup_set_bottom_margin (ps
, bottom
, state
->display_unit
);
2913 gtk_page_setup_set_left_margin (ps
, left
, state
->display_unit
);
2914 gtk_page_setup_set_right_margin (ps
, right
, state
->display_unit
);
2919 print_info_set_edge_to_above_footer (state
->pi
, footer
* factor
);
2920 print_info_set_edge_to_below_header (state
->pi
, header
* factor
);
2924 do_fetch_hf (PrinterSetupState
*state
)
2926 gnm_print_hf_free (state
->pi
->header
);
2927 gnm_print_hf_free (state
->pi
->footer
);
2929 state
->pi
->header
= gnm_print_hf_copy (state
->header
);
2930 state
->pi
->footer
= gnm_print_hf_copy (state
->footer
);
2934 do_fetch_page_info (PrinterSetupState
*state
)
2936 GnmPrintInformation
*pi
= state
->pi
;
2939 pi
->print_grid_lines
= gtk_toggle_button_get_active
2940 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state
->gui
, "check-grid-lines")));
2941 pi
->print_even_if_only_styles
= gtk_toggle_button_get_active
2942 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state
->gui
, "check-only-styles")));
2943 pi
->print_black_and_white
= gtk_toggle_button_get_active
2944 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state
->gui
, "check-black-white")));
2945 pi
->print_titles
= gtk_toggle_button_get_active
2946 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state
->gui
, "check-print-titles")));
2947 pi
->print_across_then_down
= gtk_toggle_button_get_active
2948 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state
->gui
, "radio-order-right")));
2949 pi
->do_not_print
= gtk_toggle_button_get_active
2950 (GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget (state
->gui
, "check-do-not-print")));
2952 g_free (pi
->repeat_top
);
2953 pi
->repeat_top
= g_strdup (gnm_expr_entry_get_text (state
->top_entry
));
2955 g_free (pi
->repeat_left
);
2956 pi
->repeat_left
= g_strdup (gnm_expr_entry_get_text (state
->left_entry
));
2958 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (state
->error_display
.combo
), &iter
))
2959 gtk_tree_model_get (GTK_TREE_MODEL (state
->error_display
.store
), &iter
,
2960 1, &(pi
->error_display
),
2962 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (state
->comment_display
.combo
), &iter
))
2963 gtk_tree_model_get (GTK_TREE_MODEL (state
->comment_display
.store
), &iter
,
2964 1, &(pi
->comment_placement
),
2969 fetch_settings (PrinterSetupState
*state
)
2971 do_fetch_page (state
);
2972 do_fetch_scale (state
);
2973 do_fetch_margins (state
);
2974 do_fetch_unit (state
);
2975 do_fetch_hf (state
);
2976 do_fetch_page_info (state
);
2981 dialog_printer_setup_done_cb (GtkPageSetup
*page_setup
,
2985 PrinterSetupState
*state
= data
;
2986 gnm_print_info_set_page_setup (state
->pi
,
2987 gtk_page_setup_copy (page_setup
));
2988 do_update_page (state
);
2993 dialog_gtk_printer_setup_cb (PrinterSetupState
*state
)
2995 GtkPageSetup
*page_setup
= gnm_print_info_get_page_setup (state
->pi
);
2997 gtk_print_run_page_setup_dialog_async
2998 (GTK_WINDOW (state
->dialog
),
3001 dialog_printer_setup_done_cb
,
3008 dialog_printer_setup (WBCGtk
*wbcg
, Sheet
*sheet
)
3010 PrinterSetupState
*state
;
3012 /* Only one guru per workbook. */
3013 if (wbc_gtk_get_guru (wbcg
))
3016 /* Only pop up one copy per workbook */
3017 if (gnm_dialog_raise_if_exists (wbcg
, PRINTER_SETUP_KEY
))
3020 state
= printer_setup_state_new (wbcg
, sheet
);
3024 gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state
->dialog
),
3026 GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED
);
3028 gnm_init_help_button (
3029 go_gtk_builder_get_widget (state
->gui
, "help_button"),
3030 GNUMERIC_HELP_LINK_PRINTER_SETUP_GENERAL
);
3032 wbcg
, GTK_WINDOW (state
->dialog
), PRINTER_SETUP_KEY
);
3033 gtk_widget_show (state
->dialog
);