From 18e1dc1f06ff66895c3e8cc743f4c8e13c190540 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 27 Jun 2022 17:30:22 +0200 Subject: [PATCH] I#1944 - Crash when printing task list to pdf Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1944 --- src/calendar/gui/e-cell-estimated-duration.c | 2 +- src/calendar/gui/print.c | 98 +++++++++++++++----- 2 files changed, 74 insertions(+), 26 deletions(-) diff --git a/src/calendar/gui/e-cell-estimated-duration.c b/src/calendar/gui/e-cell-estimated-duration.c index 18ccd1e5cf..0467fc0561 100644 --- a/src/calendar/gui/e-cell-estimated-duration.c +++ b/src/calendar/gui/e-cell-estimated-duration.c @@ -23,7 +23,7 @@ eced_get_text (ECellText *cell, if (!pvalue || *pvalue == 0) { e_table_model_free_value (model, col, pvalue); - return NULL; + return g_strdup (""); } res = e_cal_util_seconds_to_string (*pvalue); diff --git a/src/calendar/gui/print.c b/src/calendar/gui/print.c index c89c12ee69..6ce404e9da 100644 --- a/src/calendar/gui/print.c +++ b/src/calendar/gui/print.c @@ -57,6 +57,19 @@ struct PrintCompItem { gboolean use_24_hour_format; }; +static void +print_comp_item_free (gpointer ptr) +{ + PrintCompItem *pci = ptr; + + if (pci) { + g_clear_object (&pci->client); + g_clear_object (&pci->comp); + g_clear_object (&pci->zone); + g_slice_free (PrintCompItem, pci); + } +} + struct PrintCalItem { ECalendarView *cal_view; ETable *tasks_table; @@ -64,6 +77,19 @@ struct PrintCalItem { time_t start; }; +static void +print_cal_item_free (gpointer ptr, + GClosure *closure) +{ + PrintCalItem *pci = ptr; + + if (pci) { + g_clear_object (&pci->cal_view); + g_clear_object (&pci->tasks_table); + g_slice_free (PrintCalItem, pci); + } +} + static gdouble evo_calendar_print_renderer_get_width (GtkPrintContext *context, PangoFontDescription *font, @@ -3479,7 +3505,7 @@ print_calendar (ECalendarView *cal_view, time_t start) { GtkPrintOperation *operation; - PrintCalItem pcali; + PrintCalItem *pci; g_return_if_fail (cal_view != NULL); g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); @@ -3517,17 +3543,19 @@ print_calendar (ECalendarView *cal_view, } } - pcali.cal_view = cal_view; - pcali.tasks_table = tasks_table; - pcali.print_view_type = print_view_type; - pcali.start = start; + pci = g_slice_new0 (PrintCalItem); + pci->cal_view = g_object_ref (cal_view); + pci->tasks_table = g_object_ref (tasks_table); + pci->print_view_type = print_view_type; + pci->start = start; operation = e_print_operation_new (); gtk_print_operation_set_n_pages (operation, 1); - g_signal_connect ( + g_signal_connect_data ( operation, "draw_page", - G_CALLBACK (print_calendar_draw_page), &pcali); + G_CALLBACK (print_calendar_draw_page), pci, + print_cal_item_free, 0); gtk_print_operation_run (operation, action, NULL, NULL); @@ -3882,25 +3910,28 @@ print_comp (ECalComponent *comp, GtkPrintOperationAction action) { GtkPrintOperation *operation; - PrintCompItem pci; + PrintCompItem *pci; g_return_if_fail (E_IS_CAL_COMPONENT (comp)); - pci.comp = comp; - pci.client = cal_client; - pci.zone = zone; - pci.use_24_hour_format = use_24_hour_format; + pci = g_slice_new0 (PrintCompItem); + pci->comp = g_object_ref (comp); + pci->client = cal_client ? g_object_ref (cal_client) : NULL; + pci->zone = zone ? g_object_ref (zone) : NULL; + pci->use_24_hour_format = use_24_hour_format; operation = e_print_operation_new (); gtk_print_operation_set_n_pages (operation, 1); + g_object_set_data_full (G_OBJECT (operation), "e-print-context-data", pci, print_comp_item_free); + g_signal_connect ( operation, "begin-print", - G_CALLBACK (print_comp_begin_print), &pci); + G_CALLBACK (print_comp_begin_print), pci); g_signal_connect ( operation, "draw-page", - G_CALLBACK (print_comp_draw_page), &pci); + G_CALLBACK (print_comp_draw_page), pci); gtk_print_operation_run (operation, action, NULL, NULL); @@ -3930,20 +3961,33 @@ print_title (GtkPrintContext *context, cairo_move_to (cr, 0.0, 0.0); pango_cairo_show_layout (cr, layout); - cairo_translate (cr, 0.0, 18); - cairo_save (cr); cairo_restore (cr); + cairo_translate (cr, 0.0, 18); + g_object_unref (layout); pango_font_description_free (desc); } struct print_opts { - EPrintable *printable; - const gchar *print_header; + EPrintable *printable; + gchar *print_header; }; +static void +print_opts_free (gpointer ptr, + GClosure *closure) +{ + struct print_opts *opts = ptr; + + if (opts) { + g_clear_object (&opts->printable); + g_free (opts->print_header); + g_slice_free (struct print_opts, opts); + } +} + static void print_table_draw_page (GtkPrintOperation *operation, GtkPrintContext *context, @@ -3952,12 +3996,16 @@ print_table_draw_page (GtkPrintOperation *operation, { GtkPageSetup *setup; gdouble width; + cairo_t *cr; + cr = gtk_print_context_get_cairo_context (context); setup = gtk_print_context_get_page_setup (context); width = gtk_page_setup_get_page_width (setup, GTK_UNIT_POINTS); do { + cairo_save (cr); + /* TODO Allow the user to customize the title. */ print_title (context, opts->print_header, width); @@ -3965,9 +4013,8 @@ print_table_draw_page (GtkPrintOperation *operation, e_printable_print_page ( opts->printable, context, width, 24, TRUE); + cairo_restore (cr); } while (e_printable_data_left (opts->printable)); - - g_free (opts); } void @@ -3987,13 +4034,14 @@ print_table (ETable *table, operation = e_print_operation_new (); gtk_print_operation_set_n_pages (operation, 1); - opts = g_malloc (sizeof (struct print_opts)); - opts->printable = printable; - opts->print_header = print_header; + opts = g_slice_new0 (struct print_opts); + opts->printable = g_object_ref (printable); + opts->print_header = g_strdup (print_header); - g_signal_connect ( + g_signal_connect_data ( operation, "draw_page", - G_CALLBACK (print_table_draw_page), opts); + G_CALLBACK (print_table_draw_page), opts, + print_opts_free, 0); gtk_print_operation_run (operation, action, NULL, NULL);