[evolution/gnome-42] I#1944 - Crash when printing task list to pdf



commit 4dd94043476cccddef411235b1758b07a834833f
Author: Milan Crha <mcrha redhat com>
Date:   Mon Jun 27 17:30:22 2022 +0200

    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 43ef9e2fbe..b6338bfa5f 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);
 
@@ -3855,25 +3883,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);
 
@@ -3903,20 +3934,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,
@@ -3925,12 +3969,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);
 
@@ -3938,9 +3986,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
@@ -3960,13 +4007,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);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]