3 * print.c: Printing routines for Gnumeric
6 * Miguel de Icaza (miguel@gnu.org)
7 * Morten Welinder (terra@gnome.org)
8 * Andreas J. Guelzow (aguelzow@pyrshep.ca)
10 * Copyright 2007, Andreas J. Guelzow, All Rights Reserved
11 * Copyright (C) 2007-2009 Morten Welinder (terra@gnome.org)
13 * Handles printing of Sheets.
15 #include <gnumeric-config.h>
16 #include <print-cell.h>
23 #include <sheet-object.h>
24 #include <sheet-object-impl.h>
25 #include <selection.h>
27 #include <workbook-control.h>
29 #include <command-context.h>
30 #include <dialogs/dialogs.h>
31 #include <gnumeric-conf.h>
32 #include <libgnumeric.h>
36 #include <print-info.h>
37 #include <application.h>
38 #include <sheet-style.h>
40 #include <parse-util.h>
41 #include <style-font.h>
42 #include <gnumeric-conf.h>
43 #include <goffice/goffice.h>
45 #include <gsf/gsf-meta-names.h>
47 #include <glib/gi18n-lib.h>
48 #include <glib/gstdio.h>
56 /* see bug #533795. */
57 #define PREVIEW_VIA_PDF
60 /* The following structure is used by the printing system */
67 GtkWidget
*button_all_sheets
, *button_selected_sheet
,
69 GtkWidget
*button_selection
, *button_ignore_printarea
, *button_print_hidden_sheets
;
70 GtkWidget
*button_ignore_page_breaks
;
71 GtkWidget
*spin_from
, *spin_to
;
75 guint last_pagination
;
76 GnmPrintHFRenderInfo
*hfi
;
85 gboolean ignore_printarea
;
86 GArray
*column_pagination
;
87 GArray
*row_pagination
;
109 gnm_print_range_get_type (void)
111 static GType etype
= 0;
113 static GEnumValue
const values
[] = {
114 { GNM_PRINT_SAVED_INFO
,
115 "GNM_PRINT_SAVED_INFO",
117 { GNM_PRINT_ACTIVE_SHEET
,
118 "GNM_PRINT_ACTIVE_SHEET",
120 { GNM_PRINT_ALL_SHEETS
,
121 "GNM_PRINT_ALL_SHEETS",
123 { GNM_PRINT_ALL_SHEETS_INCLUDING_HIDDEN
,
124 "GNM_PRINT_ALL_SHEETS_INCLUDING_HIDDEN",
125 "all-sheets-incl-hidden"},
126 { GNM_PRINT_SHEET_RANGE
,
127 "GNM_PRINT_SHEET_RANGE",
129 { GNM_PRINT_SHEET_SELECTION
,
130 "GNM_PRINT_SHEET_SELECTION",
132 { GNM_PRINT_IGNORE_PRINTAREA
,
133 "GNM_PRINT_IGNORE_PRINTAREA",
134 "ignore-print-area"},
135 { GNM_PRINT_SHEET_SELECTION_IGNORE_PRINTAREA
,
136 "GNM_PRINT_SHEET_SELECTION_IGNORE_PRINTAREA",
137 "sheet-selection-ignore-printarea"},
140 etype
= g_enum_register_static ("GnmPrintRange", values
);
146 static PrintingInstance
*
147 printing_instance_new (void)
149 PrintingInstance
* pi
= g_new0 (PrintingInstance
,1);
150 pi
->hfi
= gnm_print_hf_render_info_new ();
158 sheet_print_info_free (gpointer data
)
160 SheetPrintInfo
*spi
= data
;
162 g_array_unref (spi
->column_pagination
);
163 g_array_unref (spi
->row_pagination
);
168 printing_instance_delete (PrintingInstance
*pi
)
170 g_list_free_full (pi
->gnmSheets
, sheet_print_info_free
);
171 gnm_print_hf_render_info_destroy (pi
->hfi
);
173 gtk_widget_destroy (pi
->progress
);
179 gnm_print_sheet_objects (cairo_t
*cr
,
182 double base_x
, double base_y
)
184 GSList
*ptr
, *objects
;
185 double width
, height
;
187 g_return_if_fail (IS_SHEET (sheet
));
188 g_return_if_fail (cr
!= NULL
);
189 g_return_if_fail (range
!= NULL
);
193 height
= sheet_row_get_distance_pts (sheet
, range
->start
.row
,
195 width
= sheet_col_get_distance_pts (sheet
,
196 range
->start
.col
, range
->end
.col
+ 1);
198 if (sheet
->text_is_rtl
)
200 base_x
- width
, base_y
,
208 objects
= g_slist_reverse (g_slist_copy (sheet
->sheet_objects
));
210 for (ptr
= objects
; ptr
; ptr
= ptr
->next
) {
211 SheetObject
*so
= GNM_SO (ptr
->data
);
212 GnmRange
const *r
= &so
->anchor
.cell_bound
;
214 if (!sheet_object_can_print (so
) ||
215 !range_overlap (range
, &so
->anchor
.cell_bound
))
219 /* move to top left */
220 if (sheet
->text_is_rtl
) {
222 switch (so
->anchor
.mode
) {
223 case GNM_SO_ANCHOR_ABSOLUTE
:
224 tr_x
= base_x
- 0.5; /* because of leading gridline */
227 case GNM_SO_ANCHOR_ONE_CELL
:
229 - sheet_col_get_distance_pts (sheet
, 0, r
->start
.col
+1)
230 + sheet_col_get_distance_pts (sheet
, 0, range
->start
.col
);
232 + sheet_row_get_distance_pts (sheet
, 0, r
->start
.row
)
233 - sheet_row_get_distance_pts (sheet
, 0, range
->start
.row
);
237 - sheet_col_get_distance_pts (sheet
, 0, r
->end
.col
+1)
238 + sheet_col_get_distance_pts (sheet
, 0, range
->start
.col
);
240 + sheet_row_get_distance_pts (sheet
, 0, r
->start
.row
)
241 - sheet_row_get_distance_pts (sheet
, 0, range
->start
.row
);
244 cairo_translate (cr
, tr_x
, tr_y
);
246 cairo_translate (cr
, (so
->anchor
.mode
== GNM_SO_ANCHOR_ABSOLUTE
)?
247 base_x
+ 0.5: base_x
+ 0.5
248 + sheet_col_get_distance_pts (sheet
, 0, r
->start
.col
)
249 - sheet_col_get_distance_pts (sheet
, 0,
251 (so
->anchor
.mode
== GNM_SO_ANCHOR_ABSOLUTE
)?
252 base_y
+ 0.5: base_y
+ 0.5
253 + sheet_row_get_distance_pts (sheet
, 0, r
->start
.row
)
254 - sheet_row_get_distance_pts (sheet
, 0,
257 sheet_object_draw_cairo (so
, (gpointer
)cr
, sheet
->text_is_rtl
);
261 g_slist_free (objects
);
267 print_page_cells (G_GNUC_UNUSED GtkPrintContext
*context
,
268 G_GNUC_UNUSED PrintingInstance
* pi
,
269 cairo_t
*cr
, Sheet
const *sheet
, GnmRange
*range
,
270 double base_x
, double base_y
)
272 gnm_gtk_print_cell_range (cr
, sheet
, range
,
274 (GnmPrintInformation
const *) sheet
->print_info
);
275 gnm_print_sheet_objects (cr
, sheet
, range
, base_x
, base_y
);
279 print_header_gtk (GtkPrintContext
*context
, cairo_t
*cr
,
280 double x
, double y
, double w
, double h
,
282 PangoFontDescription
*desc
)
288 cairo_rectangle (cr
, x
, y
, w
, h
);
289 cairo_set_source_rgb (cr
, 0.8, 0.8, 0.8);
292 cairo_set_source_rgb (cr
, 0., 0., 0.);
293 layout
= gtk_print_context_create_pango_layout (context
);
294 pango_layout_set_font_description (layout
, desc
);
296 pango_layout_set_text (layout
, name
, -1);
297 pango_layout_set_width (layout
, w
);
298 pango_layout_set_alignment (layout
, PANGO_ALIGN_CENTER
);
300 pango_layout_get_size (layout
, NULL
, &layout_height
);
301 text_height
= (gdouble
)layout_height
/ PANGO_SCALE
;
303 cairo_move_to (cr
, x
+ w
/2, y
+ (h
- text_height
) / 2);
304 pango_cairo_show_layout (cr
, layout
);
306 g_object_unref (layout
);
311 print_page_col_headers (GtkPrintContext
*context
,
312 G_GNUC_UNUSED PrintingInstance
* pi
,
313 cairo_t
*cr
, Sheet
const *sheet
, GnmRange
*range
,
314 double row_header_width
, double col_header_height
)
316 int start_col
, end_col
;
319 PangoFontDescription
*desc
;
322 g_return_if_fail (IS_SHEET (sheet
));
323 g_return_if_fail (range
!= NULL
);
324 g_return_if_fail (range
->start
.col
<= range
->end
.col
);
326 hscale
= sheet
->display_formulas
? 2 : 1;
327 desc
= pango_font_description_from_string ("sans 12");
329 start_col
= range
->start
.col
;
330 end_col
= range
->end
.col
;
332 x
= (row_header_width
+ GNM_COL_MARGIN
) * (sheet
->text_is_rtl
? -1. : 1.);
334 for (col
= start_col
; col
<= end_col
; col
++) {
335 ColRowInfo
const *ci
= sheet_col_get_info (sheet
, col
);
338 if (sheet
->text_is_rtl
)
339 x
-= ci
->size_pts
* hscale
;
341 print_header_gtk (context
, cr
,
343 ci
->size_pts
* hscale
- 1,
344 col_header_height
- 0.5,
345 col_name (col
), desc
);
347 if (!sheet
->text_is_rtl
)
348 x
+= ci
->size_pts
* hscale
;
352 pango_font_description_free (desc
);
356 print_page_row_headers (GtkPrintContext
*context
,
357 G_GNUC_UNUSED PrintingInstance
* pi
,
358 cairo_t
*cr
, Sheet
const *sheet
, GnmRange
*range
,
359 double row_header_width
, double col_header_height
)
361 int start_row
, end_row
;
364 PangoFontDescription
*desc
;
366 g_return_if_fail (IS_SHEET (sheet
));
367 g_return_if_fail (range
!= NULL
);
368 g_return_if_fail (range
->start
.row
<= range
->end
.row
);
370 desc
= pango_font_description_from_string ("sans 12");
372 start_row
= range
->start
.row
;
373 end_row
= range
->end
.row
;
375 if (sheet
->text_is_rtl
)
376 x
= - (row_header_width
- 0.5);
378 for (row
= start_row
, y
= col_header_height
; row
<= end_row
; row
++) {
379 ColRowInfo
const *ri
= sheet_row_get_info (sheet
, row
);
382 print_header_gtk (context
, cr
,
384 row_header_width
- 0.5,
386 row_name (row
), desc
);
391 pango_font_description_free (desc
);
395 ensure_decoration_layout (GtkPrintContext
*context
)
401 layout
= gtk_print_context_create_pango_layout (context
);
402 style
= gnm_conf_get_printer_decoration_font ();
403 font
= gnm_style_get_font
404 (style
, pango_layout_get_context (layout
));
405 pango_layout_set_font_description (layout
, font
->go
.font
->desc
);
406 gnm_style_unref (style
);
414 * @pj: printing context
419 * Print a header/footer line.
421 * Position at y, and clip to rectangle.
424 print_hf_element (GtkPrintContext
*context
, cairo_t
*cr
,
425 G_GNUC_UNUSED Sheet
const *sheet
,
427 PangoAlignment side
, gdouble width
, gboolean align_bottom
,
428 GnmPrintHFRenderInfo
*hfi
)
432 gdouble text_height
= 0.;
438 text
= gnm_print_hf_format_render (format
, hfi
, HF_RENDER_PRINT
);
443 layout
= ensure_decoration_layout (context
);
445 pango_layout_set_text (layout
, text
, -1);
446 pango_layout_set_width (layout
, width
* PANGO_SCALE
);
447 pango_layout_set_alignment (layout
, side
);
450 gint layout_height
= 0;
451 pango_layout_get_size (layout
, NULL
, &layout_height
);
452 text_height
= (gdouble
)layout_height
/ PANGO_SCALE
;
455 cairo_move_to (cr
, 0., - text_height
);
456 pango_cairo_show_layout (cr
, layout
);
458 g_object_unref (layout
);
464 * @hf: header/footer descriptor
465 * @align_bottom: vertical position (whether to print above or below
466 * @width: width of header line
468 * Print a header/footer line.
472 print_hf_line (GtkPrintContext
*context
, cairo_t
*cr
, Sheet
const *sheet
,
473 GnmPrintHF
const *hf
, gboolean align_bottom
, gdouble width
, GnmPrintHFRenderInfo
*hfi
)
475 print_hf_element (context
, cr
, sheet
, hf
->left_format
, PANGO_ALIGN_LEFT
, width
, align_bottom
, hfi
);
476 print_hf_element (context
, cr
, sheet
, hf
->middle_format
, PANGO_ALIGN_CENTER
, width
, align_bottom
, hfi
);
477 print_hf_element (context
, cr
, sheet
, hf
->right_format
, PANGO_ALIGN_RIGHT
, width
, align_bottom
, hfi
);
484 * @pj: printing context
485 * @gsr: the page information
487 * Excel prints repeated rows like this: Pages up to and including the page
488 * where the first of the repeated rows "naturally" occurs are printed in
489 * the normal way. On subsequent pages, repated rows are printed before the
493 print_page (G_GNUC_UNUSED GtkPrintOperation
*operation
,
494 GtkPrintContext
*context
,
495 PrintingInstance
* pi
,
498 Sheet
*sheet
= gsr
->sheet
;
499 GnmPrintInformation
*pinfo
= sheet
->print_info
;
500 gdouble print_height
, print_width
;
501 gdouble main_height
, main_width
;
502 gdouble header
, footer
, left
, right
;
503 gdouble edge_to_below_header
, edge_to_above_footer
;
508 gdouble col_header_height
= 0.;
509 gdouble row_header_width
= 0.;
510 gdouble rep_row_height
= 0.;
511 gdouble rep_col_width
= 0.;
512 gdouble dir
= (sheet
->text_is_rtl
? -1. : 1.);
513 GnmRange r_repeating_intersect
;
515 px
= pinfo
->scaling
.percentage
.x
/ 100.;
516 py
= pinfo
->scaling
.percentage
.y
/ 100.;
523 cr
= gtk_print_context_get_cairo_context (context
);
524 print_info_get_margins (pinfo
, &header
, &footer
, &left
, &right
,
525 &edge_to_below_header
, &edge_to_above_footer
);
527 if (sheet
->print_info
->print_titles
) {
528 col_header_height
= sheet
->rows
.default_style
.size_pts
;
529 row_header_width
= sheet
->cols
.default_style
.size_pts
;
532 width
= gtk_print_context_get_width (context
);
533 height
= print_info_get_paper_height (pinfo
,GTK_UNIT_POINTS
)
534 - edge_to_below_header
- edge_to_above_footer
;
536 main_height
= sheet_row_get_distance_pts (sheet
, gsr
->range
.start
.row
,
537 gsr
->range
.end
.row
+ 1);
538 main_width
= sheet_col_get_distance_pts (sheet
, gsr
->range
.start
.col
,
539 gsr
->range
.end
.col
+ 1);
540 if (gsr
->n_rep_rows
> 0)
541 rep_row_height
= sheet_row_get_distance_pts
542 (sheet
, gsr
->first_rep_rows
,
543 gsr
->first_rep_rows
+ gsr
->n_rep_rows
);
544 if (gsr
->n_rep_cols
> 0)
545 rep_col_width
= sheet_col_get_distance_pts
546 (sheet
, gsr
->first_rep_cols
,
547 gsr
->first_rep_cols
+ gsr
->n_rep_cols
);
548 if ((gsr
->n_rep_rows
> 0) || (gsr
->n_rep_cols
> 0)) {
549 range_init (&r_repeating_intersect
, gsr
->first_rep_cols
, gsr
->first_rep_rows
,
550 gsr
->first_rep_cols
+ gsr
->n_rep_cols
- 1,
551 gsr
->first_rep_rows
+ gsr
->n_rep_rows
- 1);
554 print_height
= main_height
+ col_header_height
+ rep_row_height
;
555 print_width
= main_width
+ row_header_width
+ rep_col_width
;
557 /* printing header */
559 if (edge_to_below_header
> header
) {
561 print_hf_line (context
, cr
, sheet
, pinfo
->header
,
562 FALSE
, width
, pi
->hfi
);
566 /* printing footer */
568 if (edge_to_above_footer
> footer
) {
570 cairo_translate (cr
, 0, height
+ (edge_to_below_header
- header
) + (edge_to_above_footer
- footer
));
571 print_hf_line (context
, cr
, sheet
, pinfo
->footer
, TRUE
, width
,
576 /* setting up content area */
578 cairo_translate (cr
, sheet
->text_is_rtl
? width
: 0, edge_to_below_header
- header
);
580 if (sheet
->sheet_type
== GNM_SHEET_OBJECT
) {
581 SheetObject
*so
= sheet
->sheet_objects
582 ? sheet
->sheet_objects
->data
585 cairo_scale (cr
, px
, py
);
586 sheet_object_draw_cairo_sized (so
, cr
, width
, height
);
590 if (pinfo
->center_horizontally
== 1 || pinfo
->center_vertically
== 1) {
594 if (pinfo
->center_horizontally
== 1)
595 shift_x
= (width
- print_width
* px
)/2;
596 if (pinfo
->center_vertically
== 1)
597 shift_y
= (height
- print_height
* py
)/2;
598 cairo_translate (cr
, dir
* shift_x
, shift_y
);
600 cairo_scale (cr
, px
, py
);
602 /* printing column and row headers */
604 if (sheet
->print_info
->print_titles
) {
606 if (gsr
->n_rep_cols
> 0) {
607 print_page_col_headers (context
, pi
, cr
, sheet
,
608 &r_repeating_intersect
,
609 row_header_width
, col_header_height
);
610 cairo_translate (cr
, dir
* rep_col_width
, 0 );
612 print_page_col_headers (context
, pi
, cr
, sheet
, &gsr
->range
,
613 row_header_width
, col_header_height
);
616 if (gsr
->n_rep_rows
> 0) {
617 print_page_row_headers (context
, pi
, cr
, sheet
,
618 &r_repeating_intersect
,
619 row_header_width
, col_header_height
);
620 cairo_translate (cr
, 0, rep_row_height
);
622 print_page_row_headers (context
, pi
, cr
, sheet
, &gsr
->range
,
623 row_header_width
, col_header_height
);
625 cairo_translate (cr
, dir
* row_header_width
, col_header_height
);
628 /* printing repeated row/col intersect */
630 if ((gsr
->n_rep_rows
> 0) && (gsr
->n_rep_cols
> 0)) {
631 print_page_cells (context
, pi
, cr
, sheet
,
632 &r_repeating_intersect
,
633 dir
* GNM_COL_MARGIN
, -GNM_ROW_MARGIN
);
636 /* printing repeated rows */
638 if (gsr
->n_rep_rows
> 0) {
640 range_init (&r
, gsr
->range
.start
.col
, gsr
->first_rep_rows
,
641 gsr
->range
.end
.col
, gsr
->first_rep_rows
+ gsr
->n_rep_rows
- 1);
643 if (gsr
->n_rep_cols
> 0)
644 cairo_translate (cr
, dir
* rep_col_width
, 0 );
645 print_page_cells (context
, pi
, cr
, sheet
, &r
,
646 dir
* GNM_COL_MARGIN
, -GNM_ROW_MARGIN
);
648 cairo_translate (cr
, 0, rep_row_height
);
651 /* printing repeated cols */
653 if (gsr
->n_rep_cols
> 0) {
655 range_init (&r
, gsr
->first_rep_cols
, gsr
->range
.start
.row
,
656 gsr
->first_rep_cols
+ gsr
->n_rep_cols
- 1, gsr
->range
.end
.row
);
657 print_page_cells (context
, pi
, cr
, sheet
, &r
,
658 dir
* GNM_COL_MARGIN
, -GNM_ROW_MARGIN
);
659 cairo_translate (cr
, dir
* rep_col_width
, 0 );
662 /* printing page content */
664 print_page_cells (context
, pi
, cr
, sheet
, &gsr
->range
,
665 dir
* GNM_COL_MARGIN
, -GNM_ROW_MARGIN
);
673 * Computes number of rows or columns that fit in @usable starting
674 * at index @start and limited to index @end
677 compute_group (Sheet
const *sheet
,
678 int start
, int end
, double usable
,
679 ColRowInfo
const *(get_info
)(Sheet
const *sheet
, int const p
))
681 double size_pts
= 1.; /* The initial grid line */
684 for (idx
= start
; idx
<= end
; idx
++, count
++) {
685 ColRowInfo
const *info
= (*get_info
) (sheet
, idx
);
687 size_pts
+= info
->size_pts
;
688 if (size_pts
> usable
)
693 /* FIXME : Find a way to inform the user that one of the rows/cols does
698 g_warning (_("Even one cell is too large for this page."));
700 /* If we do not return at least one we are going into an infinite loop! */
708 adjust_repetition (Sheet
const *sheet
,
713 gint
*first_rep_used
,
715 gdouble
*repeating_used
,
716 double (sheet_get_distance_pts
) (Sheet
const *sheet
, int from
, int to
))
719 *first_rep_used
= first_rep
;
720 if (i
- first_rep
< n_rep
) {
721 *n_rep_used
= i
- first_rep
;
722 *repeating_used
= sheet_get_distance_pts
723 (sheet
, first_rep
, first_rep
+ *n_rep_used
);
725 *repeating_used
= repeating
;
732 paginate (GArray
*paginationInfo
,
734 gint start
, gint end
,
735 gdouble usable
, gboolean repeat
, gint repeat_start
, gint repeat_end
,
736 double (sheet_get_distance_pts
) (Sheet
const *sheet
, int from
, int to
),
737 ColRowInfo
const *(get_info
)(Sheet
const *sheet
, int const p
),
738 GnmPageBreaks
*pb
, gboolean store_breaks
)
741 gint n_rep
= 0, first_rep
= 0;
742 gdouble repeating
= 0.;
746 first_rep
= repeat_start
;
747 n_rep
= repeat_end
- first_rep
+ 1;
748 repeating
= sheet_get_distance_pts (sheet
, first_rep
, first_rep
+ n_rep
);
754 n_end
= gnm_page_breaks_get_next_manual_break (pb
, rc
) - 1;
758 while (rc
<= n_end
) {
761 gdouble repeating_used
= 0.;
762 gint n_rep_used
= 0, first_rep_used
= 0;
764 adjust_repetition (sheet
, rc
,
767 &first_rep_used
, &n_rep_used
,
769 sheet_get_distance_pts
);
771 count
= compute_group (sheet
, rc
, n_end
,
772 usable
- repeating_used
,
775 if (paginationInfo
) {
779 item
.first_rep
= first_rep_used
;
780 item
.n_rep
= n_rep_used
;
781 g_array_append_val (paginationInfo
, item
);
786 if (store_breaks
&& (rc
< n_end
))
787 gnm_page_breaks_set_break (pb
, rc
, GNM_PAGE_BREAK_AUTO
);
794 /* computer_scale_fit_to
795 * Computes the scaling needed to fit all the rows or columns into the @usable
797 * This function is called when printing, and the user has selected the 'fit-to'
798 * printing option. It will adjust the internal x and y scaling values to
799 * make the sheet fit the desired number of pages, as suggested by the user.
800 * It will only reduce the scaling to fit inside a page, not enlarge.
803 compute_scale_fit_to (Sheet
const *sheet
,
804 int start
, int end
, double usable
,
805 ColRowInfo
const *(get_info
)(Sheet
const *sheet
, int const p
),
806 double (get_distance_pts
) (Sheet
const *sheet
, int from
, int to
),
807 gint pages
, double max_percent
, double header
,
808 gboolean repeat
, gint repeat_start
, gint repeat_end
, GnmPageBreaks
*pb
)
814 extent
= get_distance_pts (sheet
, start
, end
+ 1);
816 /* If the repeating columns are not included we should add them */
817 if (repeat
&& (repeat_start
< start
))
818 extent
+= get_distance_pts (sheet
, repeat_start
,
819 (repeat_end
< start
) ? (repeat_end
+ 1) : start
);
821 /* This means to take whatever space is needed. */
825 /* We can handle a single page easily: */
827 max_p
= usable
/(header
+ extent
+ 2.);
828 return ((max_p
> max_percent
) ? max_percent
: max_p
);
831 /* There is no easy way to calculate really which percentage is needed */
832 /* without in fact allocating the cols/rows to pages. */
834 /* We first calculate the max percentage needed */
836 max_p
= (pages
* usable
)/(extent
+ pages
* header
);
837 max_p
= CLAMP (max_p
, 0.01, max_percent
);
839 max_pages
= paginate (NULL
, sheet
, start
, end
, usable
/max_p
- header
,
840 repeat
, repeat_start
, repeat_end
,
841 get_distance_pts
, get_info
, pb
, FALSE
);
843 if (max_pages
== pages
)
846 /* The we calculate the min percentage */
848 min_p
= usable
/(extent
+ header
);
849 min_p
= CLAMP (min_p
, 0.01, max_percent
);
851 paginate (NULL
, sheet
, start
, end
, usable
/min_p
- header
,
852 repeat
, repeat_start
, repeat_end
,
853 get_distance_pts
, get_info
, pb
, FALSE
);
856 /* And then we pick the middle until the percentage is within 0.1% of */
857 /* the desired percentage */
859 while (max_p
- min_p
> 0.001) {
860 double cur_p
= (max_p
+ min_p
) / 2.;
861 int cur_pages
= paginate (NULL
, sheet
, start
, end
, usable
/cur_p
- header
,
862 repeat
, repeat_start
, repeat_end
,
863 get_distance_pts
, get_info
, pb
, FALSE
);
865 if (cur_pages
> pages
)
874 #define COL_FIT(col) (MIN (col, gnm_sheet_get_last_col (sheet)))
875 #define ROW_FIT(row) (MIN (row, gnm_sheet_get_last_row (sheet)))
878 compute_sheet_pages_add_sheet (PrintingInstance
* pi
, Sheet
const *sheet
,
880 gboolean ignore_printarea
)
882 SheetPrintInfo
*spi
= g_new0 (SheetPrintInfo
, 1);
884 spi
->sheet
= (Sheet
*) sheet
;
885 spi
->selection
= selection
;
886 spi
->ignore_printarea
= ignore_printarea
;
887 pi
->gnmSheets
= g_list_append(pi
->gnmSheets
, spi
);
891 print_get_sheet (PrintingInstance
*pi
, guint page_no
)
895 for (l
= pi
->gnmSheets
; l
!= NULL
; l
= l
->next
) {
896 SheetPrintInfo
*spi
= l
->data
;
897 if (spi
->pages
> page_no
)
900 page_no
-= spi
->pages
;
906 static SheetPageRange
*
907 print_get_sheet_page_range (PrintingInstance
*pi
, guint page_no
)
911 for (l
= pi
->gnmSheets
; l
!= NULL
; l
= l
->next
) {
912 SheetPrintInfo
*spi
= l
->data
;
913 if (spi
->pages
> page_no
) {
916 PaginationInfo
*c_info
, *r_info
;
917 Sheet
*sheet
= spi
->sheet
;
919 if (sheet
->print_info
->print_across_then_down
) {
920 col
= page_no
% spi
->column_pagination
->len
;
921 row
= page_no
/ spi
->column_pagination
->len
;
923 col
= page_no
/ spi
->row_pagination
->len
;
924 row
= page_no
% spi
->row_pagination
->len
;
926 g_return_val_if_fail (col
< spi
->column_pagination
->len
&&
927 row
< spi
->row_pagination
->len
, NULL
);
928 gsr
= g_new (SheetPageRange
,1);
929 c_info
= &(g_array_index (spi
->column_pagination
,
930 PaginationInfo
, col
));
931 r_info
= &(g_array_index (spi
->row_pagination
,
932 PaginationInfo
, row
));
933 range_init (&gsr
->range
,
934 COL_FIT (c_info
->rc
), ROW_FIT (r_info
->rc
),
935 COL_FIT (c_info
->rc
+ c_info
->count
- 1),
936 ROW_FIT (r_info
->rc
+ r_info
->count
- 1));
937 gsr
->n_rep_cols
= c_info
->n_rep
;
938 gsr
->first_rep_cols
= c_info
->first_rep
;
939 gsr
->n_rep_rows
= r_info
->n_rep
;
940 gsr
->first_rep_rows
= r_info
->first_rep
;
944 page_no
-= spi
->pages
;
951 return TRUE in case of trouble
955 compute_sheet_pages (GtkPrintContext
*context
,
956 PrintingInstance
* pi
,
959 Sheet
*sheet
= spi
->sheet
;
960 GnmPrintInformation
*pinfo
= sheet
->print_info
;
962 GnmRange
const *selection_range
;
964 gdouble col_header_height
= 0.;
965 gdouble row_header_width
= 0.;
966 gdouble page_width
, page_height
;
967 gdouble top_margin
, bottom_margin
, edge_to_below_header
, edge_to_above_footer
;
969 gdouble usable_x
, usable_y
;
970 GArray
*column_pagination
= g_array_sized_new
971 (FALSE
, TRUE
, sizeof (PaginationInfo
), 100);
972 GArray
*row_pagination
= g_array_sized_new
973 (FALSE
, TRUE
, sizeof (PaginationInfo
), 100);
974 gboolean repeat_top_use
, repeat_left_use
;
975 int repeat_top_start
, repeat_top_end
, repeat_left_start
, repeat_left_end
;
976 double const hscale
= sheet
->display_formulas
? 2 : 1;
978 if (pinfo
->print_titles
) {
979 col_header_height
= sheet
->rows
.default_style
.size_pts
;
980 row_header_width
= sheet
->cols
.default_style
.size_pts
;
983 print_area
= sheet_get_printarea (sheet
,
984 pinfo
->print_even_if_only_styles
,
985 spi
->ignore_printarea
);
986 if (spi
->selection
) {
987 selection_range
= selection_first_range
988 (sheet_get_view (sheet
, wb_control_view (pi
->wbc
)),
989 GO_CMD_CONTEXT (pi
->wbc
), _("Print Selection"));
990 if (selection_range
== NULL
)
992 if (spi
->ignore_printarea
) {
993 print_area
= *selection_range
;
995 if (!range_intersection (&r
, selection_range
, &print_area
))
1001 page_width
= gtk_print_context_get_width (context
);
1002 page_height
= gtk_print_context_get_height (context
);
1003 print_info_get_margins (pinfo
, &top_margin
, &bottom_margin
, NULL
, NULL
,
1004 &edge_to_below_header
, &edge_to_above_footer
);
1005 page_height
-= ((edge_to_below_header
- top_margin
)
1006 + (edge_to_above_footer
- bottom_margin
));
1008 repeat_top_use
= print_load_repeat_range (pinfo
->repeat_top
, &r
, sheet
);
1009 repeat_top_start
= repeat_top_use
? r
.start
.row
: 0;
1010 repeat_top_end
= repeat_top_use
? r
.end
.row
: 0;
1012 repeat_left_use
= print_load_repeat_range (pinfo
->repeat_left
, &r
, sheet
);
1013 repeat_left_start
= repeat_left_use
? r
.start
.col
: 0;
1014 repeat_left_end
= repeat_left_use
? r
.end
.col
: 0;
1016 if (!pi
->ignore_pb
) {
1017 if (pinfo
->page_breaks
.h
== NULL
)
1018 print_info_set_breaks (pinfo
,
1019 gnm_page_breaks_new (FALSE
));
1021 gnm_page_breaks_clean (pinfo
->page_breaks
.h
);
1022 if (pinfo
->page_breaks
.v
== NULL
)
1023 print_info_set_breaks (pinfo
,
1024 gnm_page_breaks_new (TRUE
));
1026 gnm_page_breaks_clean (pinfo
->page_breaks
.v
);
1030 if (pinfo
->scaling
.type
== PRINT_SCALE_FIT_PAGES
) {
1031 /* Note that the resulting scale is independent from */
1032 /* whether we print first down or across! */
1035 pxy
= compute_scale_fit_to (sheet
, print_area
.start
.row
, print_area
.end
.row
,
1036 page_height
, sheet_row_get_info
,
1037 sheet_row_get_distance_pts
,
1038 pinfo
->scaling
.dim
.rows
, 1.,
1041 repeat_top_start
, repeat_top_end
,
1042 pi
->ignore_pb
? NULL
: pinfo
->page_breaks
.h
);
1043 pxy
= compute_scale_fit_to (sheet
, print_area
.start
.col
, print_area
.end
.col
,
1044 page_width
, sheet_col_get_info
,
1045 sheet_col_get_distance_pts
,
1046 pinfo
->scaling
.dim
.cols
, pxy
,
1049 repeat_left_start
, repeat_left_end
,
1050 pi
->ignore_pb
? NULL
: pinfo
->page_breaks
.v
);
1052 pinfo
->scaling
.percentage
.x
= pxy
* 100.;
1053 pinfo
->scaling
.percentage
.y
= pxy
* 100.;
1056 px
= pinfo
->scaling
.percentage
.x
/ 100.;
1057 py
= pinfo
->scaling
.percentage
.y
/ 100.;
1064 usable_x
= page_width
/ px
;
1065 usable_y
= page_height
/ py
;
1067 paginate (column_pagination
, sheet
, print_area
.start
.col
, print_area
.end
.col
,
1068 (usable_x
- row_header_width
)/hscale
,
1069 repeat_left_use
, repeat_left_start
, repeat_left_end
,
1070 sheet_col_get_distance_pts
, sheet_col_get_info
,
1071 pi
->ignore_pb
? NULL
: pinfo
->page_breaks
.v
, !pi
->ignore_pb
);
1072 paginate (row_pagination
, sheet
, print_area
.start
.row
, print_area
.end
.row
,
1073 usable_y
- col_header_height
,
1074 repeat_top_use
, repeat_top_start
, repeat_top_end
,
1075 sheet_row_get_distance_pts
, sheet_row_get_info
,
1076 pi
->ignore_pb
? NULL
: pinfo
->page_breaks
.h
, !pi
->ignore_pb
);
1078 spi
->column_pagination
= column_pagination
;
1079 spi
->row_pagination
= row_pagination
;
1080 spi
->pages
= column_pagination
->len
* row_pagination
->len
;
1086 * Computes the pages that will be output by a specific
1090 compute_pages (G_GNUC_UNUSED GtkPrintOperation
*operation
,
1091 PrintingInstance
* pi
)
1093 Workbook
*wb
= pi
->wb
;
1097 PrintRange pr
= pi
->pr
;
1098 guint from
= pi
->from
;
1102 case GNM_PRINT_SAVED_INFO
:
1103 /* This should never happen. */
1104 case GNM_PRINT_ACTIVE_SHEET
:
1105 compute_sheet_pages_add_sheet (pi
, pi
->sheet
, FALSE
, FALSE
);
1107 case GNM_PRINT_ALL_SHEETS
:
1108 n
= workbook_sheet_count (wb
);
1109 for (i
= 0; i
< n
; i
++) {
1110 Sheet
*sheet
= workbook_sheet_by_index (wb
, i
);
1111 if (sheet
->print_info
->do_not_print
)
1113 if (!sheet_is_visible(sheet
))
1115 compute_sheet_pages_add_sheet (pi
, sheet
,
1119 case GNM_PRINT_ALL_SHEETS_INCLUDING_HIDDEN
:
1120 n
= workbook_sheet_count (wb
);
1121 for (i
= 0; i
< n
; i
++) {
1122 Sheet
*sheet
= workbook_sheet_by_index (wb
, i
);
1123 if (sheet
->print_info
->do_not_print
)
1125 compute_sheet_pages_add_sheet (pi
, sheet
,
1129 case GNM_PRINT_SHEET_RANGE
:
1132 n
= workbook_sheet_count (wb
);
1134 for (i
= 0; i
< n
; i
++){
1135 Sheet
*sheet
= workbook_sheet_by_index (wb
, i
);
1136 if (sheet_is_visible(sheet
))
1140 if (sheet
->print_info
->do_not_print
)
1142 if ((ct
>= from
) && (ct
<= to
))
1143 compute_sheet_pages_add_sheet (pi
, sheet
,
1147 case GNM_PRINT_SHEET_SELECTION
:
1148 compute_sheet_pages_add_sheet (pi
, pi
->sheet
, TRUE
, FALSE
);
1150 case GNM_PRINT_IGNORE_PRINTAREA
:
1151 compute_sheet_pages_add_sheet (pi
, pi
->sheet
, FALSE
, TRUE
);
1153 case GNM_PRINT_SHEET_SELECTION_IGNORE_PRINTAREA
:
1154 compute_sheet_pages_add_sheet (pi
, pi
->sheet
, TRUE
, TRUE
);
1162 static PrintJobInfo
*
1163 print_job_info_get (Sheet
*sheet
, PrintRange range
, gboolean
const preview
)
1165 PrintJobInfo
*pj
= g_new0 (PrintJobInfo
, 1);
1167 pj
->gp_config
= print_info_make_config (sheet
->print_info
);
1169 /* Values that should be entered in a dialog box */
1171 pj
->end_page
= workbook_sheet_count (sheet
->workbook
) - 1;
1173 pj
->sorted_print
= TRUE
;
1174 pj
->is_preview
= preview
;
1175 pj
->current_output_sheet
= 0;
1180 pj
->render_info
= gnm_print_hf_render_info_new ();
1181 pj
->render_info
->sheet
= sheet
;
1182 pj
->render_info
->page
= 1;
1188 print_job_info_destroy (PrintJobInfo
*pj
)
1190 g_object_unref (pj
->gp_config
);
1191 gnm_print_hf_render_info_destroy (pj
->render_info
);
1192 if (pj
->decoration_layout
)
1193 g_object_unref (pj
->decoration_layout
);
1194 if (pj
->print_context
)
1195 g_object_unref (pj
->print_context
);
1202 gnm_paginate_cb (GtkPrintOperation
*operation
,
1203 GtkPrintContext
*context
,
1206 PrintingInstance
* pi
= (PrintingInstance
*) user_data
;
1207 guint paginate
= (pi
->last_pagination
)++;
1208 SheetPrintInfo
*spi
;
1210 if (gnm_debug_flag ("print"))
1211 g_printerr ("paginate %d\n", paginate
);
1213 spi
= g_list_nth_data (pi
->gnmSheets
, paginate
);
1214 if (spi
== NULL
) { /*We are done paginating */
1215 /* GTK sends additional pagination requests! */
1216 /* We only need to do this once though! */
1217 if (g_list_nth_data (pi
->gnmSheets
, paginate
- 1) != NULL
) {
1221 for (l
= pi
->gnmSheets
; l
!= NULL
; l
= l
->next
) {
1222 SheetPrintInfo
*spi
= l
->data
;
1223 n_pages
+= spi
->pages
;
1226 if (pi
->preview
&& n_pages
> 1000) {
1229 gtk_print_operation_set_n_pages
1230 (operation
, n_pages
== 0 ? 1 : n_pages
);
1231 for (i
= 0; i
< n_pages
; i
++) {
1232 if (gtk_print_operation_preview_is_selected
1233 (GTK_PRINT_OPERATION_PREVIEW (operation
),
1239 if (count
> 1000 && !go_gtk_query_yes_no
1240 (pi
->progress
!= NULL
?
1241 GTK_WINDOW (pi
->progress
) : wbcg_toplevel (WBC_GTK (pi
->wbc
)),
1243 _("You have chosen more than 1000 pages to preview. "
1244 "This may take a long time. "
1245 "Do you really want to proceed?")))
1249 gtk_print_operation_set_n_pages (operation
, n_pages
== 0 ? 1 : n_pages
);
1250 gtk_print_operation_set_unit (operation
, GTK_UNIT_POINTS
);
1251 pi
->hfi
->pages
= n_pages
;
1253 if (n_pages
== 0) /* gtk+ cannot handle 0 pages */
1254 gtk_print_operation_cancel (operation
);
1259 if (compute_sheet_pages (context
, pi
, spi
)) {
1260 gtk_print_operation_cancel (operation
);
1268 cb_progress_response (G_GNUC_UNUSED GtkDialog
*dialog
,
1269 G_GNUC_UNUSED gint response_id
,
1270 PrintingInstance
*pi
)
1276 cb_progress_delete (G_GNUC_UNUSED GtkWidget
*widget
,
1277 G_GNUC_UNUSED GdkEvent
*event
,
1278 PrintingInstance
*pi
)
1285 gnm_ready_preview_cb (G_GNUC_UNUSED GtkPrintOperation
*operation
,
1286 G_GNUC_UNUSED GtkPrintOperationPreview
*preview
,
1287 G_GNUC_UNUSED GtkPrintContext
*context
,
1288 G_GNUC_UNUSED GtkWindow
*parent
,
1291 PrintingInstance
* pi
= (PrintingInstance
*) user_data
;
1298 gnm_begin_print_cb (GtkPrintOperation
*operation
,
1299 G_GNUC_UNUSED GtkPrintContext
*context
,
1302 PrintingInstance
* pi
= (PrintingInstance
*) user_data
;
1304 if (gnm_debug_flag ("print"))
1305 g_printerr ("begin-print\n");
1308 /* Working around gtk+ bug 423484. */
1309 GtkPrintSettings
*settings
= gtk_print_operation_get_print_settings (operation
);
1310 gtk_print_settings_set_int
1311 (settings
, GNUMERIC_PRINT_SETTING_PRINT_FROM_SHEET_KEY
,
1313 gtk_print_settings_set_int
1314 (settings
, GNUMERIC_PRINT_SETTING_PRINT_TO_SHEET_KEY
,
1316 gtk_print_settings_set_int
1317 (settings
, GNUMERIC_PRINT_SETTING_PRINTRANGE_KEY
, pi
->pr
);
1318 gtk_print_settings_set_int
1319 (settings
, GNUMERIC_PRINT_SETTING_IGNORE_PAGE_BREAKS_KEY
, pi
->ignore_pb
? 1 : 0);
1322 if (NULL
!= pi
->wbc
&& GNM_IS_WBC_GTK(pi
->wbc
)) {
1323 pi
->progress
= gtk_message_dialog_new (wbcg_toplevel (WBC_GTK (pi
->wbc
)),
1325 GTK_DIALOG_DESTROY_WITH_PARENT
,
1328 "%s", /* please clang */
1330 _("Preparing to preview"):
1331 _("Preparing to print"));
1332 g_signal_connect (G_OBJECT (pi
->progress
), "response",
1333 G_CALLBACK (cb_progress_response
), pi
);
1334 g_signal_connect (G_OBJECT (pi
->progress
), "delete-event",
1335 G_CALLBACK (cb_progress_delete
), pi
);
1336 gtk_widget_show_all (pi
->progress
);
1339 compute_pages (operation
, pi
);
1343 gnm_end_print_cb (G_GNUC_UNUSED GtkPrintOperation
*operation
,
1344 G_GNUC_UNUSED GtkPrintContext
*context
,
1345 G_GNUC_UNUSED gpointer user_data
)
1347 if (gnm_debug_flag ("print"))
1348 g_printerr ("end-print\n");
1352 cp_gtk_page_setup (GtkPageSetup
*from
, GtkPageSetup
*to
)
1354 gtk_page_setup_set_paper_size (to
, gtk_page_setup_get_paper_size (from
));
1355 gtk_page_setup_set_orientation (to
,gtk_page_setup_get_orientation (from
));
1356 gtk_page_setup_set_top_margin
1357 (to
, gtk_page_setup_get_top_margin (from
, GTK_UNIT_MM
), GTK_UNIT_MM
);
1358 gtk_page_setup_set_bottom_margin
1359 (to
, gtk_page_setup_get_bottom_margin (from
, GTK_UNIT_MM
), GTK_UNIT_MM
);
1360 gtk_page_setup_set_left_margin
1361 (to
, gtk_page_setup_get_left_margin (from
, GTK_UNIT_MM
), GTK_UNIT_MM
);
1362 gtk_page_setup_set_right_margin
1363 (to
, gtk_page_setup_get_right_margin (from
, GTK_UNIT_MM
), GTK_UNIT_MM
);
1367 gnm_request_page_setup_cb (GtkPrintOperation
*operation
,
1368 G_GNUC_UNUSED GtkPrintContext
*context
,
1370 GtkPageSetup
*setup
,
1373 PrintingInstance
* pi
= (PrintingInstance
*) user_data
;
1375 GtkPrintSettings
* settings
= gtk_print_operation_get_print_settings
1378 g_return_if_fail (pi
!= NULL
);
1380 sheet
= print_get_sheet (pi
, page_nr
);
1382 if (sheet
== NULL
) {
1383 /* g_warning ("Avoiding gtk+ bug 492498"); */
1387 gtk_print_settings_set_use_color (settings
, !sheet
->print_info
->print_black_and_white
);
1388 if (sheet
->print_info
->page_setup
== NULL
)
1389 gnm_print_info_load_defaults (sheet
->print_info
);
1390 if (sheet
->print_info
->page_setup
!= NULL
)
1391 cp_gtk_page_setup (sheet
->print_info
->page_setup
, setup
);
1395 gnm_draw_page_cb (GtkPrintOperation
*operation
,
1396 GtkPrintContext
*context
,
1401 PrintingInstance
* pi
= (PrintingInstance
*) user_data
;
1402 SheetPageRange
* gsr
;
1404 if (gnm_debug_flag ("print"))
1405 g_printerr ("draw-page %d\n", page_nr
);
1408 gtk_print_operation_cancel (operation
);
1409 g_signal_handlers_disconnect_by_func
1410 (G_OBJECT (operation
), G_CALLBACK (gnm_draw_page_cb
), user_data
);
1414 gsr
= print_get_sheet_page_range (pi
, page_nr
);
1419 if (pi
->hfi
->pages
== -1)
1420 text
= g_strdup_printf
1421 (pi
->preview
? _("Creating preview of page %3d")
1422 : _("Printing page %3d"), page_nr
);
1424 text
= g_strdup_printf
1426 ngettext("Creating preview of page %3d of %3d page",
1427 "Creating preview of page %3d of %3d pages",
1429 : ngettext("Printing page %3d of %3d page",
1430 "Printing page %3d of %3d pages",
1432 page_nr
, pi
->hfi
->pages
);
1433 g_object_set (G_OBJECT (pi
->progress
), "text", text
, NULL
);
1436 pi
->hfi
->page
= page_nr
+ 1;
1437 pi
->hfi
->sheet
= gsr
->sheet
;
1438 pi
->hfi
->page_area
= gsr
->range
;
1439 pi
->hfi
->top_repeating
= gsr
->range
.start
;
1440 if (gsr
->n_rep_cols
> 0)
1441 pi
->hfi
->top_repeating
.col
= gsr
->first_rep_cols
;
1442 if (gsr
->n_rep_rows
> 0)
1443 pi
->hfi
->top_repeating
.row
= gsr
->first_rep_rows
;
1444 print_page (operation
, context
, pi
, gsr
);
1450 widget_button_cb (GtkToggleButton
*togglebutton
, GtkWidget
*check
)
1452 gtk_widget_set_sensitive (check
, gtk_toggle_button_get_active (togglebutton
));
1456 workbook_visible_sheet_count (Workbook
*wb
)
1459 guint n
= workbook_sheet_count (wb
);
1462 for (i
= 0; i
< n
; i
++) {
1463 Sheet
*sheet
= workbook_sheet_by_index (wb
, i
);
1464 if (sheet_is_visible(sheet
))
1471 gnm_create_widget_cb (GtkPrintOperation
*operation
, gpointer user_data
)
1473 PrintingInstance
* pi
= (PrintingInstance
*) user_data
;
1475 GtkWidget
*button_all_sheets
, *button_selected_sheet
, *button_spec_sheets
;
1476 GtkWidget
*button_selection
, *button_ignore_printarea
;
1477 GtkWidget
*button_print_hidden_sheets
;
1478 GtkWidget
*label_from
, *label_to
;
1479 GtkWidget
*spin_from
, *spin_to
;
1480 GtkWidget
*button_ignore_page_breaks
;
1481 GtkPrintSettings
* settings
;
1482 guint n_sheets
= workbook_visible_sheet_count (pi
->wb
);
1484 if (gnm_debug_flag ("print"))
1485 g_printerr ("Creating custom print widget\n");
1487 grid
= gtk_grid_new ();
1489 "column-spacing", 12,
1494 button_all_sheets
= gtk_radio_button_new_with_mnemonic (NULL
,
1495 _("_All workbook sheets"));
1496 gtk_widget_set_hexpand (button_all_sheets
, TRUE
);
1497 gtk_grid_attach (GTK_GRID (grid
), button_all_sheets
, 0, 0, 5, 1);
1499 button_print_hidden_sheets
= gtk_check_button_new_with_mnemonic
1500 (_("Also print _hidden sheets"));
1501 g_object_set (button_print_hidden_sheets
,
1505 gtk_grid_attach (GTK_GRID (grid
), button_print_hidden_sheets
, 0, 1, 5, 1);
1507 button_selected_sheet
= gtk_radio_button_new_with_mnemonic_from_widget
1508 (GTK_RADIO_BUTTON (button_all_sheets
), _("A_ctive workbook sheet"));
1509 gtk_widget_set_hexpand (button_selected_sheet
, TRUE
);
1510 gtk_grid_attach (GTK_GRID (grid
), button_selected_sheet
, 0, 2, 5, 1);
1512 button_spec_sheets
= gtk_radio_button_new_with_mnemonic_from_widget
1513 (GTK_RADIO_BUTTON (button_all_sheets
), _("_Workbook sheets:"));
1514 gtk_widget_set_hexpand (button_spec_sheets
, TRUE
);
1515 gtk_grid_attach (GTK_GRID (grid
), button_spec_sheets
, 0, 5, 1, 1);
1517 button_selection
= gtk_check_button_new_with_mnemonic
1518 (_("Current _selection only"));
1519 g_object_set (button_selection
,
1523 gtk_grid_attach (GTK_GRID (grid
), button_selection
, 0, 3, 5, 1);
1525 button_ignore_printarea
= gtk_check_button_new_with_mnemonic
1526 (_("_Ignore defined print area"));
1527 g_object_set (button_ignore_printarea
,
1531 gtk_grid_attach (GTK_GRID (grid
), button_ignore_printarea
, 0, 4, 5, 1);
1533 label_from
= gtk_label_new (_("from:"));
1534 g_object_set (label_from
,
1538 gtk_grid_attach (GTK_GRID (grid
), label_from
, 1, 5, 1, 1);
1540 spin_from
= gtk_spin_button_new_with_range (1, n_sheets
, 1);
1541 gtk_widget_set_hexpand (spin_from
, TRUE
);
1542 gtk_grid_attach (GTK_GRID (grid
), spin_from
, 2, 5, 1, 1);
1544 label_to
= gtk_label_new (_("to:"));
1545 gtk_widget_set_hexpand (label_to
, TRUE
);
1546 gtk_grid_attach (GTK_GRID (grid
), label_to
, 3, 5, 1, 1);
1548 spin_to
= gtk_spin_button_new_with_range (1, n_sheets
, 1);
1549 gtk_widget_set_hexpand (spin_to
, TRUE
);
1550 gtk_grid_attach (GTK_GRID (grid
), spin_to
, 4, 5, 1, 1);
1551 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_to
), n_sheets
);
1553 button_ignore_page_breaks
= gtk_separator_new (GTK_ORIENTATION_HORIZONTAL
);
1554 gtk_widget_set_hexpand (button_ignore_page_breaks
, TRUE
);
1555 gtk_grid_attach (GTK_GRID (grid
), button_ignore_page_breaks
, 0, 6, 5, 1);
1557 button_ignore_page_breaks
= gtk_check_button_new_with_mnemonic (_("Ignore all _manual page breaks"));
1558 gtk_widget_set_hexpand (button_ignore_page_breaks
, TRUE
);
1559 gtk_grid_attach (GTK_GRID (grid
), button_ignore_page_breaks
, 0, 7, 5, 1);
1560 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_ignore_page_breaks
), TRUE
);
1562 g_signal_connect_after (G_OBJECT (button_selected_sheet
), "toggled",
1563 G_CALLBACK (widget_button_cb
), button_selection
);
1564 g_signal_connect_after (G_OBJECT (button_selected_sheet
), "toggled",
1565 G_CALLBACK (widget_button_cb
), button_ignore_printarea
);
1567 g_signal_connect_after (G_OBJECT (button_all_sheets
), "toggled",
1568 G_CALLBACK (widget_button_cb
), button_print_hidden_sheets
);
1570 g_signal_connect_after (G_OBJECT (button_spec_sheets
), "toggled",
1571 G_CALLBACK (widget_button_cb
), label_from
);
1572 g_signal_connect_after (G_OBJECT (button_spec_sheets
), "toggled",
1573 G_CALLBACK (widget_button_cb
), label_to
);
1574 g_signal_connect_after (G_OBJECT (button_spec_sheets
), "toggled",
1575 G_CALLBACK (widget_button_cb
), spin_from
);
1576 g_signal_connect_after (G_OBJECT (button_spec_sheets
), "toggled",
1577 G_CALLBACK (widget_button_cb
), spin_to
);
1579 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_selected_sheet
), TRUE
);
1581 settings
= gtk_print_operation_get_print_settings (operation
);
1584 switch (gtk_print_settings_get_int_with_default
1585 (settings
, GNUMERIC_PRINT_SETTING_PRINTRANGE_KEY
,
1586 GNM_PRINT_ACTIVE_SHEET
)) {
1587 case GNM_PRINT_SHEET_SELECTION_IGNORE_PRINTAREA
:
1588 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_ignore_printarea
), TRUE
);
1590 case GNM_PRINT_SHEET_SELECTION
:
1591 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_selection
), TRUE
);
1593 case GNM_PRINT_ACTIVE_SHEET
:
1594 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_selected_sheet
), TRUE
);
1596 case GNM_PRINT_IGNORE_PRINTAREA
:
1597 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_ignore_printarea
), TRUE
);
1598 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_selected_sheet
), TRUE
);
1600 case GNM_PRINT_SHEET_RANGE
:
1601 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_spec_sheets
), TRUE
);
1603 case GNM_PRINT_ALL_SHEETS_INCLUDING_HIDDEN
:
1604 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_print_hidden_sheets
), TRUE
);
1606 case GNM_PRINT_ALL_SHEETS
:
1607 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_all_sheets
), TRUE
);
1611 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_from
),
1612 gtk_print_settings_get_int_with_default
1613 (settings
, GNUMERIC_PRINT_SETTING_PRINT_FROM_SHEET_KEY
,
1615 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_to
),
1616 gtk_print_settings_get_int_with_default
1617 (settings
, GNUMERIC_PRINT_SETTING_PRINT_TO_SHEET_KEY
,
1619 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_ignore_page_breaks
),
1620 0 != gtk_print_settings_get_int_with_default
1621 (settings
, GNUMERIC_PRINT_SETTING_IGNORE_PAGE_BREAKS_KEY
,
1625 /* We are sending toggled signals to ensure that all widgets are */
1626 /* correctly enabled or disabled. */
1627 gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (button_selected_sheet
));
1628 gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (button_spec_sheets
));
1630 gtk_widget_show_all (grid
);
1632 /* Let's save the widgets */
1633 pi
->button_all_sheets
= button_all_sheets
;
1634 pi
->button_selected_sheet
= button_selected_sheet
;
1635 pi
->button_spec_sheets
= button_spec_sheets
;
1636 pi
->button_selection
= button_selection
;
1637 pi
->button_ignore_printarea
= button_ignore_printarea
;
1638 pi
->button_print_hidden_sheets
= button_print_hidden_sheets
;
1639 pi
->spin_from
= spin_from
;
1640 pi
->spin_to
= spin_to
;
1641 pi
->button_ignore_page_breaks
= button_ignore_page_breaks
;
1643 if (gnm_debug_flag ("print"))
1644 g_printerr ("Done with creating custom print widget\n");
1646 return G_OBJECT (grid
);
1650 gnm_custom_widget_apply_cb (GtkPrintOperation
*operation
,
1651 G_GNUC_UNUSED GtkWidget
*widget
,
1654 PrintingInstance
* pi
= (PrintingInstance
*) user_data
;
1655 GtkPrintSettings
* settings
;
1656 PrintRange pr
= GNM_PRINT_ACTIVE_SHEET
;
1660 settings
= gtk_print_operation_get_print_settings (operation
);
1662 g_return_if_fail (settings
!= NULL
);
1664 from
= gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pi
->spin_from
));
1665 to
= gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pi
->spin_to
));
1667 gtk_print_settings_set_int (settings
,
1668 GNUMERIC_PRINT_SETTING_PRINT_FROM_SHEET_KEY
,
1670 gtk_print_settings_set_int (settings
,
1671 GNUMERIC_PRINT_SETTING_PRINT_TO_SHEET_KEY
,
1676 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pi
->button_all_sheets
))) {
1677 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pi
->button_print_hidden_sheets
)))
1678 pr
= GNM_PRINT_ALL_SHEETS_INCLUDING_HIDDEN
;
1680 pr
= GNM_PRINT_ALL_SHEETS
;
1681 } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pi
->button_spec_sheets
))) {
1682 pr
= GNM_PRINT_SHEET_RANGE
;
1683 } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pi
->button_selected_sheet
))) {
1684 gboolean ignore_printarea
= gtk_toggle_button_get_active
1685 (GTK_TOGGLE_BUTTON (pi
->button_ignore_printarea
));
1686 gboolean selection
= gtk_toggle_button_get_active
1687 (GTK_TOGGLE_BUTTON (pi
->button_selection
));
1688 if (selection
&& ignore_printarea
)
1689 pr
= GNM_PRINT_SHEET_SELECTION_IGNORE_PRINTAREA
;
1691 pr
= GNM_PRINT_SHEET_SELECTION
;
1692 else if (ignore_printarea
)
1693 pr
= GNM_PRINT_IGNORE_PRINTAREA
;
1695 pr
= GNM_PRINT_ACTIVE_SHEET
;
1698 gtk_print_settings_set_int (settings
,
1699 GNUMERIC_PRINT_SETTING_PRINTRANGE_KEY
, pr
);
1703 ignore_pb
= gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pi
->button_ignore_page_breaks
)) ? 1 : 0;
1704 gtk_print_settings_set_int (settings
, GNUMERIC_PRINT_SETTING_IGNORE_PAGE_BREAKS_KEY
,
1706 pi
->ignore_pb
= ignore_pb
;
1710 cb_delete_and_free (char *tmp_file_name
)
1712 if (tmp_file_name
) {
1713 g_unlink (tmp_file_name
);
1714 g_free (tmp_file_name
);
1719 gnm_print_uri_change_extension (char const *uri
, GtkPrintSettings
* settings
)
1721 const gchar
*ext
= gtk_print_settings_get
1723 GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT
);
1728 gint uri_len
= strlen(uri
);
1732 gtk_print_settings_set (settings
,
1733 GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT
,
1737 base
= g_path_get_basename (uri
);
1738 used_ext
= strrchr (base
, '.');
1739 if (used_ext
== NULL
)
1740 return g_strconcat (uri
, ".", ext
, NULL
);
1741 strip
= strlen (base
) - (used_ext
- base
);
1742 res
= g_strndup (uri
, uri_len
- strip
+ 1 + strlen (ext
));
1743 res
[uri_len
- strip
] = '.';
1744 strcpy (res
+ uri_len
- strip
+ 1, ext
);
1749 gnm_print_sheet (WorkbookControl
*wbc
, Sheet
*sheet
,
1750 gboolean preview
, PrintRange default_range
,
1751 GsfOutput
*export_dst
)
1753 GtkPrintOperation
*print
;
1754 GtkPrintOperationResult res
;
1755 GtkPageSetup
*page_setup
;
1756 PrintingInstance
*pi
;
1757 GtkPrintSettings
* settings
;
1758 GtkWindow
*parent
= NULL
;
1759 GtkPrintOperationAction action
;
1760 gchar
*tmp_file_name
= NULL
;
1761 int tmp_file_fd
= -1;
1762 gboolean preview_via_pdf
= FALSE
;
1763 PrintRange pr_translator
[] = {GNM_PRINT_ACTIVE_SHEET
, GNM_PRINT_ALL_SHEETS
,
1764 GNM_PRINT_ALL_SHEETS
, GNM_PRINT_ACTIVE_SHEET
,
1765 GNM_PRINT_SHEET_SELECTION
, GNM_PRINT_ACTIVE_SHEET
,
1766 GNM_PRINT_SHEET_SELECTION_IGNORE_PRINTAREA
};
1768 gchar
*output_uri
= NULL
;
1769 gchar
const *saved_uri
= NULL
;
1771 #ifdef PREVIEW_VIA_PDF
1772 preview_via_pdf
= preview
;
1775 g_return_if_fail (sheet
!= NULL
&& sheet
->workbook
!= NULL
);
1778 g_return_if_fail (!export_dst
&& wbc
);
1780 doc
= GO_DOC (sheet
->workbook
);
1782 print
= gtk_print_operation_new ();
1784 pi
= printing_instance_new ();
1785 pi
->wb
= sheet
->workbook
;
1786 pi
->wbc
= wbc
? GNM_WBC (wbc
) : NULL
;
1788 pi
->preview
= preview
;
1790 settings
= gnm_conf_get_print_settings ();
1791 if (default_range
== GNM_PRINT_SAVED_INFO
) {
1792 gint dr
= print_info_get_printrange (sheet
->print_info
);
1793 if (dr
< 0 || dr
>= (gint
)G_N_ELEMENTS (pr_translator
))
1794 default_range
= GNM_PRINT_ACTIVE_SHEET
;
1796 default_range
= pr_translator
[dr
];
1798 gtk_print_settings_set_int (settings
,
1799 GNUMERIC_PRINT_SETTING_PRINTRANGE_KEY
,
1801 pi
->pr
= default_range
;
1802 gtk_print_settings_set_use_color (settings
,
1803 !sheet
->print_info
->print_black_and_white
);
1804 if (!export_dst
&& !preview_via_pdf
&& !preview
) {
1805 /* We should be setting the output file name to something */
1807 saved_uri
= print_info_get_printtofile_uri (sheet
->print_info
);
1808 if (saved_uri
!= NULL
&&
1809 g_ascii_strncasecmp (doc
->uri
, "file:///", 8) == 0)
1810 output_uri
= gnm_print_uri_change_extension (saved_uri
,
1814 if (output_uri
== NULL
&& doc
->uri
!= NULL
1815 && g_ascii_strncasecmp (doc
->uri
, "file:///", 8) == 0)
1816 output_uri
= gnm_print_uri_change_extension (doc
->uri
,
1818 if (output_uri
!= NULL
) {
1819 gtk_print_settings_set (settings
,
1820 GTK_PRINT_SETTINGS_OUTPUT_URI
,
1822 g_free (output_uri
);
1826 gtk_print_operation_set_print_settings (print
, settings
);
1827 g_object_unref (settings
);
1829 page_setup
= gnm_print_info_get_page_setup (sheet
->print_info
);
1831 gtk_print_operation_set_default_page_setup (print
, page_setup
);
1833 g_signal_connect (print
, "preview", G_CALLBACK (gnm_ready_preview_cb
), pi
);
1834 g_signal_connect (print
, "begin-print", G_CALLBACK (gnm_begin_print_cb
), pi
);
1835 g_signal_connect (print
, "paginate", G_CALLBACK (gnm_paginate_cb
), pi
);
1836 g_signal_connect (print
, "draw-page", G_CALLBACK (gnm_draw_page_cb
), pi
);
1837 g_signal_connect (print
, "end-print", G_CALLBACK (gnm_end_print_cb
), pi
);
1838 g_signal_connect (print
, "request-page-setup", G_CALLBACK (gnm_request_page_setup_cb
), pi
);
1840 gtk_print_operation_set_use_full_page (print
, FALSE
);
1841 gtk_print_operation_set_unit (print
, GTK_UNIT_POINTS
);
1843 if (NULL
!= wbc
&& GNM_IS_WBC_GTK(wbc
))
1844 parent
= wbcg_toplevel (WBC_GTK (wbc
));
1846 if (preview_via_pdf
|| export_dst
) {
1849 tmp_file_fd
= g_file_open_tmp ("gnmXXXXXX.pdf",
1850 &tmp_file_name
, &err
);
1853 gsf_output_set_error (export_dst
, 0,
1854 "%s", err
->message
);
1856 char *text
= g_strdup_printf
1857 (_("Failed to create temporary file for printing: %s"),
1859 go_cmd_context_error_export
1860 (GO_CMD_CONTEXT (wbc
), text
);
1867 action
= GTK_PRINT_OPERATION_ACTION_EXPORT
;
1868 gtk_print_operation_set_export_filename (print
, tmp_file_name
);
1869 gtk_print_operation_set_show_progress (print
, FALSE
);
1872 ? GTK_PRINT_OPERATION_ACTION_PREVIEW
1873 : GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
;
1874 gtk_print_operation_set_show_progress (print
, FALSE
);
1875 gtk_print_operation_set_custom_tab_label (print
, _("Gnumeric Print Range"));
1876 g_signal_connect (print
, "create-custom-widget", G_CALLBACK (gnm_create_widget_cb
), pi
);
1877 g_signal_connect (print
, "custom-widget-apply", G_CALLBACK (gnm_custom_widget_apply_cb
), pi
);
1880 res
= gtk_print_operation_run (print
, action
, parent
, NULL
);
1883 case GTK_PRINT_OPERATION_RESULT_APPLY
:
1884 if (action
== GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
) {
1885 char const *printer
;
1886 settings
= gtk_print_operation_get_print_settings (print
);
1887 gnm_conf_set_print_settings (settings
);
1888 gnm_insert_meta_date (doc
, GSF_META_NAME_PRINT_DATE
);
1889 printer
= gtk_print_settings_get_printer (settings
);
1890 if (strcmp (printer
, "Print to File") == 0 ||
1891 strcmp (printer
, _("Print to File")) == 0) {
1892 gchar
*wb_output_uri
=
1893 gnm_print_uri_change_extension (doc
->uri
,
1895 print_info_set_printtofile_from_settings
1896 (sheet
->print_info
, settings
, wb_output_uri
);
1897 g_free (wb_output_uri
);
1900 print_info_set_from_settings
1901 (sheet
->print_info
, settings
);
1903 case GTK_PRINT_OPERATION_RESULT_CANCEL
:
1905 case GTK_PRINT_OPERATION_RESULT_ERROR
:
1907 case GTK_PRINT_OPERATION_RESULT_IN_PROGRESS
:
1908 /* This can only happen if we were allowing asynchronous operation */
1912 printing_instance_delete (pi
);
1914 if (preview_via_pdf
) {
1916 /* For some reason the general code doesn't work for me.
1917 Be brutal, even if this might not work for non-ASCII
1919 int res
= (int)ShellExecute (NULL
, "open",
1924 if (gnm_debug_flag ("preview")) {
1925 g_printerr ("tmp_file_name=%s\n", tmp_file_name
);
1926 g_printerr ("res=%d\n", res
);
1929 GdkScreen
*screen
= parent
1930 ? gtk_widget_get_screen (GTK_WIDGET (parent
))
1932 char *url
= go_filename_to_uri (tmp_file_name
);
1933 go_gtk_url_show (url
, screen
);
1937 /* We hook this up to delete the temp file when the workbook
1938 is closed or when a new preview is done for the same
1939 workbook. That's not perfect, but good enough while
1940 we wait for gtk+ to fix printing. */
1941 g_object_set_data_full (G_OBJECT (wbc
),
1942 "temp-file", tmp_file_name
,
1943 (GDestroyNotify
)cb_delete_and_free
);
1944 tmp_file_name
= NULL
;
1945 } else if (tmp_file_name
) {
1946 char buffer
[64 * 1024];
1949 if (lseek (tmp_file_fd
, 0, SEEK_SET
) < 0)
1952 while ((bytes_read
= read (tmp_file_fd
, buffer
, sizeof (buffer
))) > 0) {
1953 gsf_output_write (export_dst
, bytes_read
, buffer
);
1956 if (bytes_read
< 0) {
1957 int save_errno
= errno
;
1958 if (!gsf_output_error (export_dst
))
1959 gsf_output_set_error (export_dst
,
1960 g_file_error_from_errno (save_errno
),
1961 "%s", g_strerror (save_errno
));
1966 if (tmp_file_fd
>= 0)
1967 close (tmp_file_fd
);
1968 cb_delete_and_free (tmp_file_name
);
1970 g_object_unref (print
);
1974 gnm_draw_so_page_cb (G_GNUC_UNUSED GtkPrintOperation
*operation
,
1975 GtkPrintContext
*context
,
1976 G_GNUC_UNUSED gint page_nr
,
1980 SheetObject
*so
= (SheetObject
*) user_data
;
1981 cairo_t
*cr
= gtk_print_context_get_cairo_context (context
);
1982 Sheet
*sheet
= sheet_object_get_sheet (so
);
1985 cairo_translate (cr
, 0, 0);
1986 sheet_object_draw_cairo (so
, (gpointer
)cr
, sheet
->text_is_rtl
);
1993 * @sos: (element-type SheetObject) (transfer none):
1997 gnm_print_so (WorkbookControl
*wbc
, GPtrArray
*sos
,
1998 GsfOutput
*export_dst
)
2000 GtkPrintOperation
*print
;
2001 GtkPageSetup
*page_setup
;
2002 GtkPrintSettings
* settings
;
2004 GtkWindow
*parent
= NULL
;
2005 GtkPrintOperationAction action
;
2006 gchar
*tmp_file_name
= NULL
;
2007 int tmp_file_fd
= -1;
2010 g_return_if_fail (sos
!= NULL
&& sos
->len
> 0);
2012 /* FIXME: we should print all objects in the array, not just the first! */
2014 so
= g_ptr_array_index (sos
, 0),
2015 sheet
= sheet_object_get_sheet (so
);
2016 if (NULL
!= wbc
&& GNM_IS_WBC_GTK(wbc
))
2017 parent
= wbcg_toplevel (WBC_GTK (wbc
));
2019 print
= gtk_print_operation_new ();
2021 settings
= gnm_conf_get_print_settings ();
2022 gtk_print_settings_set_use_color (settings
,
2023 !sheet
->print_info
->print_black_and_white
);
2024 gtk_print_operation_set_print_settings (print
, settings
);
2025 g_object_unref (settings
);
2027 page_setup
= gnm_print_info_get_page_setup (sheet
->print_info
);
2029 gtk_print_operation_set_default_page_setup (print
, page_setup
);
2031 gtk_print_operation_set_n_pages (print
, 1);
2032 gtk_print_operation_set_embed_page_setup (print
, TRUE
);
2034 g_signal_connect (print
, "draw-page", G_CALLBACK (gnm_draw_so_page_cb
), so
);
2036 gtk_print_operation_set_use_full_page (print
, FALSE
);
2037 gtk_print_operation_set_unit (print
, GTK_UNIT_POINTS
);
2042 tmp_file_fd
= g_file_open_tmp ("gnmXXXXXX.pdf",
2043 &tmp_file_name
, &err
);
2045 gsf_output_set_error (export_dst
, 0,
2046 "%s", err
->message
);
2048 if (tmp_file_fd
>= 0)
2049 close (tmp_file_fd
);
2050 cb_delete_and_free (tmp_file_name
);
2052 g_object_unref (print
);
2055 action
= GTK_PRINT_OPERATION_ACTION_EXPORT
;
2056 gtk_print_operation_set_export_filename (print
, tmp_file_name
);
2057 gtk_print_operation_set_show_progress (print
, FALSE
);
2059 action
= GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
;
2060 gtk_print_operation_set_show_progress (print
, TRUE
);
2063 gtk_print_operation_run (print
, action
, parent
, NULL
);
2065 if (tmp_file_name
) {
2066 char buffer
[64 * 1024];
2069 if (lseek (tmp_file_fd
, 0, SEEK_SET
) < 0)
2072 while ((bytes_read
= read
2073 (tmp_file_fd
, buffer
, sizeof (buffer
))) > 0) {
2074 gsf_output_write (export_dst
, bytes_read
, buffer
);
2077 if (bytes_read
< 0) {
2078 int save_errno
= errno
;
2079 if (!gsf_output_error (export_dst
))
2080 gsf_output_set_error (export_dst
,
2081 g_file_error_from_errno (save_errno
),
2082 "%s", g_strerror (save_errno
));
2084 close (tmp_file_fd
);
2085 cb_delete_and_free (tmp_file_name
);
2088 g_object_unref (print
);