diff options
Diffstat (limited to 'mail/e-mail-printer.c')
-rw-r--r-- | mail/e-mail-printer.c | 542 |
1 files changed, 44 insertions, 498 deletions
diff --git a/mail/e-mail-printer.c b/mail/e-mail-printer.c index 2d5af9159d..68ee6ba65b 100644 --- a/mail/e-mail-printer.c +++ b/mail/e-mail-printer.c @@ -33,6 +33,7 @@ #include "e-mail-printer.h" #include "e-mail-display.h" +#include "e-mail-print-config-headers.h" #define w(x) @@ -58,8 +59,6 @@ struct _EMailPrinterPrivate { gchar *export_filename; - GtkListStore *headers; - WebKitWebView *webview; /* WebView to print from */ gchar *uri; GtkWidget *buttons[BUTTONS_COUNT]; @@ -114,19 +113,38 @@ async_context_free (AsyncContext *async_context) g_slice_free (AsyncContext, async_context); } -static gint -mail_printer_header_name_equal (const EMailFormatterHeader *h1, - const EMailFormatterHeader *h2) +static GtkWidget * +mail_printer_create_custom_widget_cb (GtkPrintOperation *operation, + AsyncContext *async_context) { - if ((h2->value == NULL) || (h1->value == NULL)) { - return g_strcmp0 (h1->name, h2->name); - } else { - if ((g_strcmp0 (h1->name, h2->name) == 0) && - (g_strcmp0 (h1->value, h2->value) == 0)) - return 0; - else - return 1; - } + EMailDisplay *display; + EMailPartList *part_list; + EMailPart *part; + GtkWidget *widget; + + gtk_print_operation_set_custom_tab_label (operation, _("Headers")); + + display = E_MAIL_DISPLAY (async_context->web_view); + part_list = e_mail_display_get_parts_list (display); + + /* FIXME Hard-coding the part ID works for now but could easily + * break silently. Need a less brittle way of extracting + * specific parts by either MIME type or GType. */ + part = e_mail_part_list_ref_part (part_list, ".message.headers"); + + widget = e_mail_print_config_headers_new (E_MAIL_PART_HEADERS (part)); + + g_object_unref (part); + + return widget; +} + +static void +mail_printer_custom_widget_apply_cb (GtkPrintOperation *operation, + GtkWidget *widget, + AsyncContext *async_context) +{ + webkit_web_view_reload (async_context->web_view); } static void @@ -166,383 +184,6 @@ mail_printer_draw_footer_cb (GtkPrintOperation *operation, g_free (text); } -static void -set_header_visible (EMailPrinter *emp, - EMailFormatterHeader *header, - gint index, - gboolean visible) -{ - WebKitDOMDocument *document; - WebKitDOMNodeList *headers; - WebKitDOMElement *element; - WebKitDOMCSSStyleDeclaration *style; - - document = webkit_web_view_get_dom_document (emp->priv->webview); - headers = webkit_dom_document_get_elements_by_class_name (document, "header-item"); - - g_return_if_fail (index < webkit_dom_node_list_get_length (headers)); - - element = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (headers, index)); - style = webkit_dom_element_get_style (element); - webkit_dom_css_style_declaration_set_property ( - style, - "display", (visible ? "table-row" : "none"), "", NULL); -} - -static void -header_active_renderer_toggled_cb (GtkCellRendererToggle *renderer, - gchar *path, - EMailPrinter *emp) -{ - GtkTreeIter iter; - GtkTreePath *p; - gboolean active; - EMailFormatterHeader *header; - gint *indices; - - gtk_tree_model_get_iter_from_string ( - GTK_TREE_MODEL (emp->priv->headers), - &iter, path); - - gtk_tree_model_get ( - GTK_TREE_MODEL (emp->priv->headers), &iter, - COLUMN_ACTIVE, &active, -1); - gtk_tree_model_get ( - GTK_TREE_MODEL (emp->priv->headers), &iter, - COLUMN_HEADER_STRUCT, &header, -1); - gtk_list_store_set ( - GTK_LIST_STORE (emp->priv->headers), &iter, - COLUMN_ACTIVE, !active, -1); - - p = gtk_tree_path_new_from_string (path); - indices = gtk_tree_path_get_indices (p); - set_header_visible (emp, header, indices[0], !active); - gtk_tree_path_free (p); -} - -static void -emp_headers_tab_toggle_selection (GtkWidget *button, - gpointer user_data) -{ - EMailPrinter *emp = user_data; - GtkTreeIter iter; - gboolean select; - - if (button == emp->priv->buttons[BUTTON_SELECT_ALL]) - select = TRUE; - else if (button == emp->priv->buttons[BUTTON_SELECT_NONE]) - select = FALSE; - else - return; - - if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (emp->priv->headers), &iter)) - return; - - do { - EMailFormatterHeader *header; - GtkTreePath *path; - gint *indices; - - gtk_tree_model_get ( - GTK_TREE_MODEL (emp->priv->headers), &iter, - COLUMN_HEADER_STRUCT, &header, -1); - gtk_list_store_set ( - GTK_LIST_STORE (emp->priv->headers), &iter, - COLUMN_ACTIVE, select, -1); - - path = gtk_tree_model_get_path (GTK_TREE_MODEL (emp->priv->headers), &iter); - indices = gtk_tree_path_get_indices (path); - set_header_visible (emp, header, indices[0], select); - gtk_tree_path_free (path); - - } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (emp->priv->headers), &iter)); -} - -static void -emp_headers_tab_selection_changed (GtkTreeSelection *selection, - gpointer user_data) -{ - EMailPrinter *emp = user_data; - gboolean enabled; - GList *selected_rows; - GtkTreeIter iter; - GtkTreeModel *model; - GtkTreePath *path; - - if (gtk_tree_selection_count_selected_rows (selection) == 0) { - gtk_widget_set_sensitive (emp->priv->buttons[BUTTON_TOP], FALSE); - gtk_widget_set_sensitive (emp->priv->buttons[BUTTON_UP], FALSE); - gtk_widget_set_sensitive (emp->priv->buttons[BUTTON_DOWN], FALSE); - gtk_widget_set_sensitive (emp->priv->buttons[BUTTON_BOTTOM], FALSE); - - return; - } - - model = GTK_TREE_MODEL (emp->priv->headers); - selected_rows = gtk_tree_selection_get_selected_rows (selection, &model); - - path = gtk_tree_path_copy (selected_rows->data); - enabled = gtk_tree_path_prev (path); - gtk_widget_set_sensitive (emp->priv->buttons[BUTTON_TOP], enabled); - gtk_widget_set_sensitive (emp->priv->buttons[BUTTON_UP], enabled); - - gtk_tree_model_get_iter (model, &iter, g_list_last (selected_rows)->data); - enabled = gtk_tree_model_iter_next (model, &iter); - gtk_widget_set_sensitive (emp->priv->buttons[BUTTON_DOWN], enabled); - gtk_widget_set_sensitive (emp->priv->buttons[BUTTON_BOTTOM], enabled); - - g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL); - g_list_free (selected_rows); - gtk_tree_path_free (path); -} - -static void -emp_headers_tab_move (GtkWidget *button, - gpointer user_data) -{ - EMailPrinter *emp = user_data; - GtkTreeSelection *selection; - GList *selected_rows, *references, *l; - GtkTreePath *path; - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreeRowReference *selection_middle; - gint *indices; - - WebKitDOMDocument *document; - WebKitDOMNodeList *headers; - WebKitDOMNode *header, *parent; - - model = GTK_TREE_MODEL (emp->priv->headers); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (emp->priv->treeview)); - selected_rows = gtk_tree_selection_get_selected_rows (selection, &model); - - /* The order of header rows in the HMTL document should be in sync with - order of headers in the listview and in efhp->headers_list */ - document = webkit_web_view_get_dom_document (emp->priv->webview); - headers = webkit_dom_document_get_elements_by_class_name (document, "header-item"); - - l = g_list_nth (selected_rows, g_list_length (selected_rows) / 2); - selection_middle = gtk_tree_row_reference_new (model, l->data); - - references = NULL; - for (l = selected_rows; l; l = l->next) { - references = g_list_prepend ( - references, - gtk_tree_row_reference_new (model, l->data)); - } - - if (button == emp->priv->buttons[BUTTON_TOP]) { - - for (l = references; l; l = l->next) { - /* Move the rows in the view */ - path = gtk_tree_row_reference_get_path (l->data); - gtk_tree_model_get_iter (model, &iter, path); - gtk_list_store_move_after (emp->priv->headers, &iter, NULL); - - /* Move the header row in HTML document */ - indices = gtk_tree_path_get_indices (path); - header = webkit_dom_node_list_item (headers, indices[0]); - parent = webkit_dom_node_get_parent_node (header); - webkit_dom_node_remove_child (parent, header, NULL); - webkit_dom_node_insert_before (parent, header, - webkit_dom_node_get_first_child (parent), NULL); - - gtk_tree_path_free (path); - } - - } else if (button == emp->priv->buttons[BUTTON_UP]) { - - GtkTreeIter *iter_prev; - WebKitDOMNode *node2; - - references = g_list_reverse (references); - - for (l = references; l; l = l->next) { - - path = gtk_tree_row_reference_get_path (l->data); - gtk_tree_model_get_iter (model, &iter, path); - iter_prev = gtk_tree_iter_copy (&iter); - gtk_tree_model_iter_previous (model, iter_prev); - - gtk_list_store_move_before (emp->priv->headers, &iter, iter_prev); - - indices = gtk_tree_path_get_indices (path); - header = webkit_dom_node_list_item (headers, indices[0]); - node2 = webkit_dom_node_get_previous_sibling (header); - parent = webkit_dom_node_get_parent_node (header); - - webkit_dom_node_remove_child (parent, header, NULL); - webkit_dom_node_insert_before (parent, header, node2, NULL); - - gtk_tree_path_free (path); - gtk_tree_iter_free (iter_prev); - } - - } else if (button == emp->priv->buttons[BUTTON_DOWN]) { - - GtkTreeIter *iter_next; - WebKitDOMNode *node2; - - for (l = references; l; l = l->next) { - - path = gtk_tree_row_reference_get_path (l->data); - gtk_tree_model_get_iter (model, &iter, path); - iter_next = gtk_tree_iter_copy (&iter); - gtk_tree_model_iter_next (model, iter_next); - - gtk_list_store_move_after (emp->priv->headers, &iter, iter_next); - - indices = gtk_tree_path_get_indices (path); - header = webkit_dom_node_list_item (headers, indices[0]); - node2 = webkit_dom_node_get_next_sibling (header); - parent = webkit_dom_node_get_parent_node (header); - - webkit_dom_node_remove_child (parent, header, NULL); - webkit_dom_node_insert_before (parent, header, - webkit_dom_node_get_next_sibling (node2), NULL); - - gtk_tree_path_free (path); - gtk_tree_iter_free (iter_next); - } - - } else if (button == emp->priv->buttons[BUTTON_BOTTOM]) { - - references = g_list_reverse (references); - - for (l = references; l; l = l->next) { - path = gtk_tree_row_reference_get_path (l->data); - gtk_tree_model_get_iter (model, &iter, path); - gtk_list_store_move_before (emp->priv->headers, &iter, NULL); - - /* Move the header row in HTML document */ - indices = gtk_tree_path_get_indices (path); - header = webkit_dom_node_list_item (headers, indices[0]); - parent = webkit_dom_node_get_parent_node (header); - webkit_dom_node_remove_child (parent, header, NULL); - webkit_dom_node_append_child (parent, header, NULL); - - gtk_tree_path_free (path); - } - }; - - g_list_foreach (references, (GFunc) gtk_tree_row_reference_free, NULL); - g_list_free (references); - - /* Keep the selection in middle of the screen */ - path = gtk_tree_row_reference_get_path (selection_middle); - gtk_tree_view_scroll_to_cell ( - GTK_TREE_VIEW (emp->priv->treeview), - path, COLUMN_ACTIVE, TRUE, 0.5, 0.5); - gtk_tree_path_free (path); - gtk_tree_row_reference_free (selection_middle); - - g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL); - g_list_free (selected_rows); - - emp_headers_tab_selection_changed (selection, user_data); -} - -static GtkWidget * -emp_create_headers_tab (GtkPrintOperation *operation, - EMailPrinter *emp) -{ - GtkWidget *vbox, *hbox, *scw, *button; - GtkTreeView *view; - GtkTreeSelection *selection; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5); - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); - gtk_box_pack_end (GTK_BOX (hbox), vbox, FALSE, FALSE, 5); - - emp->priv->treeview = gtk_tree_view_new_with_model ( - GTK_TREE_MODEL (emp->priv->headers)); - view = GTK_TREE_VIEW (emp->priv->treeview); - selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); - g_signal_connect ( - selection, "changed", - G_CALLBACK (emp_headers_tab_selection_changed), emp); - - renderer = gtk_cell_renderer_toggle_new (); - g_signal_connect ( - renderer, "toggled", - G_CALLBACK (header_active_renderer_toggled_cb), emp); - column = gtk_tree_view_column_new_with_attributes ( - _("Print"), renderer, - "active", COLUMN_ACTIVE, NULL); - gtk_tree_view_append_column (view, column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ( - _("Header Name"), renderer, - "text", COLUMN_HEADER_NAME, NULL); - gtk_tree_view_append_column (view, column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ( - _("Header Value"), renderer, - "text", COLUMN_HEADER_VALUE, NULL); - gtk_tree_view_append_column (view, column); - - scw = gtk_scrolled_window_new (NULL, NULL); - gtk_container_add (GTK_CONTAINER (scw), GTK_WIDGET (view)); - gtk_box_pack_start (GTK_BOX (hbox), scw, TRUE, TRUE, 0); - - button = gtk_button_new_from_stock (GTK_STOCK_SELECT_ALL); - emp->priv->buttons[BUTTON_SELECT_ALL] = button; - g_signal_connect ( - button, "clicked", - G_CALLBACK (emp_headers_tab_toggle_selection), emp); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, TRUE, 5); - - button = gtk_button_new_from_stock (GTK_STOCK_CLEAR); - emp->priv->buttons[BUTTON_SELECT_NONE] = button; - g_signal_connect ( - button, "clicked", - G_CALLBACK (emp_headers_tab_toggle_selection), emp); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, TRUE, 5); - - button = gtk_button_new_from_stock (GTK_STOCK_GOTO_TOP); - emp->priv->buttons[BUTTON_TOP] = button; - gtk_widget_set_sensitive (button, FALSE); - g_signal_connect ( - button, "clicked", - G_CALLBACK (emp_headers_tab_move), emp); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, TRUE, 5); - - button = gtk_button_new_from_stock (GTK_STOCK_GO_UP); - emp->priv->buttons[BUTTON_UP] = button; - gtk_widget_set_sensitive (button, FALSE); - g_signal_connect ( - button, "clicked", - G_CALLBACK (emp_headers_tab_move), emp); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, TRUE, 5); - - button = gtk_button_new_from_stock (GTK_STOCK_GO_DOWN); - emp->priv->buttons[BUTTON_DOWN] = button; - gtk_widget_set_sensitive (button, FALSE); - g_signal_connect ( - button, "clicked", - G_CALLBACK (emp_headers_tab_move), emp); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, TRUE, 5); - - button = gtk_button_new_from_stock (GTK_STOCK_GOTO_BOTTOM); - emp->priv->buttons[BUTTON_BOTTOM] = button; - gtk_widget_set_sensitive (button, FALSE); - g_signal_connect ( - button, "clicked", - G_CALLBACK (emp_headers_tab_move), emp); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, TRUE, 5); - - gtk_print_operation_set_custom_tab_label (operation, _("Headers")); - gtk_widget_show_all (hbox); - - return hbox; -} - static gboolean mail_printer_print_timeout_cb (gpointer user_data) { @@ -554,6 +195,7 @@ mail_printer_print_timeout_cb (gpointer user_data) EMailPrinter *printer; WebKitWebFrame *web_frame; gulong create_custom_widget_handler_id; + gulong custom_widget_apply_handler_id; gulong draw_page_handler_id; GError *error = NULL; @@ -572,6 +214,7 @@ mail_printer_print_timeout_cb (gpointer user_data) G_ASYNC_RESULT (simple)); print_operation = e_print_operation_new (); + gtk_print_operation_set_show_progress (print_operation, TRUE); gtk_print_operation_set_unit (print_operation, GTK_UNIT_PIXEL); @@ -586,7 +229,13 @@ mail_printer_print_timeout_cb (gpointer user_data) create_custom_widget_handler_id = g_signal_connect ( print_operation, "create-custom-widget", - G_CALLBACK (emp_create_headers_tab), printer); + G_CALLBACK (mail_printer_create_custom_widget_cb), + async_context); + + custom_widget_apply_handler_id = g_signal_connect ( + print_operation, "custom-widget-apply", + G_CALLBACK (mail_printer_custom_widget_apply_cb), + async_context); draw_page_handler_id = g_signal_connect ( print_operation, "draw-page", @@ -627,6 +276,9 @@ mail_printer_print_timeout_cb (gpointer user_data) print_operation, create_custom_widget_handler_id); g_signal_handler_disconnect ( + print_operation, custom_widget_apply_handler_id); + + g_signal_handler_disconnect ( print_operation, draw_page_handler_id); g_object_unref (print_operation); @@ -696,74 +348,6 @@ mail_printer_load_status_cb (WebKitWebView *web_view, g_object_unref (simple); } -static void -mail_printer_build_model (EMailPrinter *printer, - EMailPartList *part_list) -{ - CamelMediumHeader *header; - CamelMimeMessage *message; - GArray *headers; - GQueue *headers_queue; - gint i; - GtkTreeIter last_known = { 0 }; - - if (printer->priv->headers != NULL) - g_object_unref (printer->priv->headers); - printer->priv->headers = gtk_list_store_new ( - 5, - G_TYPE_BOOLEAN, /* COLUMN_ACTIVE */ - G_TYPE_STRING, /* COLUMN_HEADER_NAME */ - G_TYPE_STRING, /* COLUMN_HEADER_VALUE */ - G_TYPE_POINTER, /* COLUMN_HEADER_STRUCT */ - G_TYPE_INT); /* ??? */ - - message = e_mail_part_list_get_message (part_list); - headers = camel_medium_get_headers (CAMEL_MEDIUM (message)); - if (!headers) - return; - - headers_queue = e_mail_formatter_dup_headers (printer->priv->formatter); - for (i = 0; i < headers->len; i++) { - GtkTreeIter iter; - GList *found_header; - EMailFormatterHeader *emfh; - - header = &g_array_index (headers, CamelMediumHeader, i); - emfh = e_mail_formatter_header_new (header->name, header->value); - - found_header = g_queue_find_custom ( - headers_queue, emfh, (GCompareFunc) - mail_printer_header_name_equal); - - if (!found_header) { - emfh->flags |= E_MAIL_FORMATTER_HEADER_FLAG_HIDDEN; - e_mail_formatter_add_header_struct ( - printer->priv->formatter, emfh); - gtk_list_store_append (printer->priv->headers, &iter); - } else { - if (gtk_list_store_iter_is_valid (printer->priv->headers, &last_known)) - gtk_list_store_insert_after (printer->priv->headers, &iter, &last_known); - else - gtk_list_store_insert_after (printer->priv->headers, &iter, NULL); - - last_known = iter; - } - - gtk_list_store_set ( - printer->priv->headers, &iter, - COLUMN_ACTIVE, (found_header != NULL), - COLUMN_HEADER_NAME, emfh->name, - COLUMN_HEADER_VALUE, emfh->value, - COLUMN_HEADER_STRUCT, emfh, -1); - } - - g_queue_free_full ( - headers_queue, - (GDestroyNotify) e_mail_formatter_header_free); - - camel_medium_free_headers (CAMEL_MEDIUM (message), headers); -} - static WebKitWebView * mail_printer_new_web_view (const gchar *charset, const gchar *default_charset) @@ -838,29 +422,8 @@ mail_printer_dispose (GObject *object) priv = E_MAIL_PRINTER_GET_PRIVATE (object); - if (priv->headers != NULL) { - GtkTreeModel *model; - GtkTreeIter iter; - gboolean valid; - - model = GTK_TREE_MODEL (priv->headers); - - valid = gtk_tree_model_get_iter_first (model, &iter); - while (valid) { - EMailFormatterHeader *header = NULL; - - gtk_tree_model_get ( - model, &iter, - COLUMN_HEADER_STRUCT, &header, -1); - e_mail_formatter_header_free (header); - - valid = gtk_tree_model_iter_next (model, &iter); - } - } - g_clear_object (&priv->formatter); g_clear_object (&priv->part_list); - g_clear_object (&priv->headers); g_clear_object (&priv->webview); g_clear_object (&priv->operation); @@ -882,22 +445,6 @@ mail_printer_finalize (GObject *object) } static void -mail_printer_constructed (GObject *object) -{ - EMailPrinter *printer; - EMailPartList *part_list; - - printer = E_MAIL_PRINTER (object); - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_mail_printer_parent_class)->constructed (object); - - part_list = e_mail_printer_ref_part_list (printer); - mail_printer_build_model (printer, part_list); - g_object_unref (part_list); -} - -static void e_mail_printer_class_init (EMailPrinterClass *class) { GObjectClass *object_class; @@ -909,7 +456,6 @@ e_mail_printer_class_init (EMailPrinterClass *class) object_class->get_property = mail_printer_get_property; object_class->dispose = mail_printer_dispose; object_class->finalize = mail_printer_finalize; - object_class->constructed = mail_printer_constructed; g_object_class_install_property ( object_class, |