From 64388b6b828c49827dad1159dac1482cc9840650 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 5 Jun 2013 19:30:00 -0400 Subject: Add e_mail_part_headers_ref_print_model(). Returns a GtkTreeModel of header names and values and visibility flags, built from the CamelMimeMessage. The tree model rows can be reordered and toggled prior to printing. Also add e_mail_part_headers_is_default() as a handy helper. --- em-format/e-mail-part-headers.c | 152 ++++++++++++++++++++++++++++++++++++++++ em-format/e-mail-part-headers.h | 11 +++ 2 files changed, 163 insertions(+) (limited to 'em-format') diff --git a/em-format/e-mail-part-headers.c b/em-format/e-mail-part-headers.c index 5a74376db8..9087e8e60d 100644 --- a/em-format/e-mail-part-headers.c +++ b/em-format/e-mail-part-headers.c @@ -21,6 +21,8 @@ #include #include +#include "e-mail-part-list.h" + #define E_MAIL_PART_HEADERS_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_MAIL_PART_HEADERS, EMailPartHeadersPrivate)) @@ -28,6 +30,7 @@ struct _EMailPartHeadersPrivate { GMutex property_lock; gchar **default_headers; + GtkTreeModel *print_model; }; enum { @@ -53,6 +56,86 @@ static const gchar *basic_headers[] = { NULL }; +static GtkTreeModel * +mail_part_headers_build_print_model (EMailPartHeaders *part) +{ + GtkListStore *list_store; + EMailPartList *part_list; + CamelMimeMessage *message; + GArray *array; + gint default_position = 0; + guint ii, length = 0; + + /* If the part list is NULL, it means the function was called + * too early. The part must be added to a part list first so + * we have access to the CamelMimeMessage. */ + part_list = e_mail_part_ref_part_list (E_MAIL_PART (part)); + g_return_val_if_fail (part_list != NULL, NULL); + + list_store = gtk_list_store_new ( + E_MAIL_PART_HEADERS_PRINT_MODEL_NUM_COLUMNS, + G_TYPE_BOOLEAN, /* INCLUDE */ + G_TYPE_STRING, /* HEADER_NAME */ + G_TYPE_STRING); /* HEADER_VALUE */ + + message = e_mail_part_list_get_message (part_list); + array = camel_medium_get_headers (CAMEL_MEDIUM (message)); + + if (array != NULL) + length = array->len; + + for (ii = 0; ii < length; ii++) { + CamelMediumHeader *header; + GtkTreeIter iter; + gboolean include = FALSE; + gint position = -1; + + header = &g_array_index (array, CamelMediumHeader, ii); + + /* EMailFormatterPrintHeaders excludes "Subject" from + * its header table (because it puts it in an

tag + * at the top of the page), so we'll exclude it too. */ + if (g_ascii_strncasecmp (header->name, "Subject", 7) == 0) + continue; + + /* Arrange default headers first and select them to be + * included in the final printout. All other headers + * are excluded by default in the final printout. */ + if (e_mail_part_headers_is_default (part, header->name)) { + position = default_position++; + include = TRUE; + } + + gtk_list_store_insert (list_store, &iter, position); + + gtk_list_store_set ( + list_store, &iter, + E_MAIL_PART_HEADERS_PRINT_MODEL_COLUMN_INCLUDE, + include, + E_MAIL_PART_HEADERS_PRINT_MODEL_COLUMN_HEADER_NAME, + header->name, + E_MAIL_PART_HEADERS_PRINT_MODEL_COLUMN_HEADER_VALUE, + header->value, + -1); + } + + if (array != NULL) + camel_medium_free_headers (CAMEL_MEDIUM (message), array); + + g_object_unref (part_list); + + /* Stash the print model internally. */ + + g_mutex_lock (&part->priv->property_lock); + + g_clear_object (&part->priv->print_model); + part->priv->print_model = g_object_ref (list_store); + + g_mutex_unlock (&part->priv->property_lock); + + return GTK_TREE_MODEL (list_store); +} + static void mail_part_headers_set_property (GObject *object, guint property_id, @@ -88,6 +171,19 @@ mail_part_headers_get_property (GObject *object, G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } +static void +mail_part_headers_dispose (GObject *object) +{ + EMailPartHeadersPrivate *priv; + + priv = E_MAIL_PART_HEADERS_GET_PRIVATE (object); + + g_clear_object (&priv->print_model); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_mail_part_headers_parent_class)->dispose (object); +} + static void mail_part_headers_finalize (GObject *object) { @@ -155,6 +251,7 @@ e_mail_part_headers_class_init (EMailPartHeadersClass *class) object_class = G_OBJECT_CLASS (class); object_class->set_property = mail_part_headers_set_property; object_class->get_property = mail_part_headers_get_property; + object_class->dispose = mail_part_headers_dispose; object_class->finalize = mail_part_headers_finalize; object_class->constructed = mail_part_headers_constructed; @@ -228,3 +325,58 @@ e_mail_part_headers_set_default_headers (EMailPartHeaders *part, g_object_notify (G_OBJECT (part), "default-headers"); } +gboolean +e_mail_part_headers_is_default (EMailPartHeaders *part, + const gchar *header_name) +{ + gboolean is_default = FALSE; + guint ii, length = 0; + + g_return_val_if_fail (E_IS_MAIL_PART_HEADERS (part), FALSE); + g_return_val_if_fail (header_name != NULL, FALSE); + + g_mutex_lock (&part->priv->property_lock); + + if (part->priv->default_headers != NULL) + length = g_strv_length (part->priv->default_headers); + + for (ii = 0; ii < length; ii++) { + const gchar *candidate; + + /* g_strv_length() stops on the first NULL pointer, + * so we don't have to worry about this being NULL. */ + candidate = part->priv->default_headers[ii]; + + if (g_ascii_strcasecmp (header_name, candidate) == 0) { + is_default = TRUE; + break; + } + } + + g_mutex_unlock (&part->priv->property_lock); + + return is_default; +} + +GtkTreeModel * +e_mail_part_headers_ref_print_model (EMailPartHeaders *part) +{ + GtkTreeModel *print_model = NULL; + + g_return_val_if_fail (E_IS_MAIL_PART_HEADERS (part), NULL); + + g_mutex_lock (&part->priv->property_lock); + + if (part->priv->print_model != NULL) + print_model = g_object_ref (part->priv->print_model); + + g_mutex_unlock (&part->priv->property_lock); + + if (print_model == NULL) { + /* The print model is built once on demand. */ + print_model = mail_part_headers_build_print_model (part); + } + + return print_model; +} + diff --git a/em-format/e-mail-part-headers.h b/em-format/e-mail-part-headers.h index c302637dc5..c7da98f6b4 100644 --- a/em-format/e-mail-part-headers.h +++ b/em-format/e-mail-part-headers.h @@ -58,6 +58,13 @@ struct _EMailPartHeadersClass { EMailPartClass parent_class; }; +typedef enum { + E_MAIL_PART_HEADERS_PRINT_MODEL_COLUMN_INCLUDE, + E_MAIL_PART_HEADERS_PRINT_MODEL_COLUMN_HEADER_NAME, + E_MAIL_PART_HEADERS_PRINT_MODEL_COLUMN_HEADER_VALUE, + E_MAIL_PART_HEADERS_PRINT_MODEL_NUM_COLUMNS +} EMailPartHeadersPrintModelColumns; + GType e_mail_part_headers_get_type (void) G_GNUC_CONST; EMailPart * e_mail_part_headers_new (CamelMimePart *mime_part, const gchar *id); @@ -66,6 +73,10 @@ gchar ** e_mail_part_headers_dup_default_headers void e_mail_part_headers_set_default_headers (EMailPartHeaders *part, const gchar * const *default_headers); +gboolean e_mail_part_headers_is_default (EMailPartHeaders *part, + const gchar *header_name); +GtkTreeModel * e_mail_part_headers_ref_print_model + (EMailPartHeaders *part); G_END_DECLS -- cgit v1.2.3