aboutsummaryrefslogtreecommitdiffstats
path: root/mail/e-mail-printer.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/e-mail-printer.c')
-rw-r--r--mail/e-mail-printer.c542
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,