From 70fe80d69aec73ea1f4fa830b00ac603546e135d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 24 Apr 2009 20:33:12 +0200 Subject: Sort UIDs before using them ** Fix for bug #563954 * message-list.c: (regen_list_exec): Sort UIDs before using them to obtain proper order when without sorting. --- mail/ChangeLog | 7 +++++++ mail/message-list.c | 2 ++ 2 files changed, 9 insertions(+) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index d4a9c8912f..56918b19fb 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,10 @@ +2009-04-24 Milan Crha + + ** Fix for bug #563954 + + * message-list.c: (regen_list_exec): Sort UIDs before + using them to obtain proper order when without sorting. + 2009-04-24 Milan Crha ** Fix for bug #552583 diff --git a/mail/message-list.c b/mail/message-list.c index a2a9989bda..c98ce04ace 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -4169,6 +4169,8 @@ regen_list_exec (struct _regen_list_msg *m) //camel_folder_summary_reload_from_db (m->folder->summary, NULL); if (!camel_operation_cancel_check(m->base.cancel)) { + camel_folder_sort_uids (m->folder, showuids); + /* update/build a new tree */ if (m->dotree) { if (m->tree) -- cgit From f081b36f4c0ad6220d4b0f4f41b8a60cd9af4a6c Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 24 Apr 2009 21:06:35 +0200 Subject: Do not crash on delete folder ** Fix for bug #579306 * em-folder-utils.c: (em_folder_utils_delete_folder): Do not free uninitialized variable. --- mail/ChangeLog | 7 +++++++ mail/em-folder-utils.c | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index 56918b19fb..5bbf0366b5 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,10 @@ +2009-04-24 Milan Crha + + ** Fix for bug #579306 + + * em-folder-utils.c: (em_folder_utils_delete_folder): + Do not free uninitialized variable. + 2009-04-24 Milan Crha ** Fix for bug #563954 diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c index ea177b65ce..80d4fde143 100644 --- a/mail/em-folder-utils.c +++ b/mail/em-folder-utils.c @@ -401,7 +401,6 @@ em_folder_utils_delete_folder (CamelFolder *folder) { CamelStore *local; GtkWidget *dialog; - char *uri; int flags = 0; local = mail_component_peek_local_store (NULL); @@ -418,7 +417,6 @@ em_folder_utils_delete_folder (CamelFolder *folder) return; } - g_free (uri); camel_object_ref (folder); dialog = e_error_new(NULL, -- cgit From 59f095bfb5b92f8bd0205238f91fc3a2277de76c Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 27 Apr 2009 12:29:26 +0200 Subject: Hide last junked message too from the non-junk folder ** Fix for bug #579635 --- mail/ChangeLog | 7 +++++++ mail/message-list.c | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index 5bbf0366b5..586cb1b7bf 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,10 @@ +2009-04-27 Milan Crha + + ** Fix for bug #579635 + + * message-list.c: (regen_list_exec): Do not keep last junked messages + in a message list for folders not showing junks. + 2009-04-24 Milan Crha ** Fix for bug #579306 diff --git a/mail/message-list.c b/mail/message-list.c index c98ce04ace..3027fcf3e8 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -4056,7 +4056,8 @@ regen_list_exec (struct _regen_list_msg *m) CamelMessageInfo *looking_info = camel_folder_get_message_info (m->folder, looking_for); if (looking_info) { - gboolean was_deleted = (camel_message_info_flags (looking_info) & CAMEL_MESSAGE_DELETED) != 0; + gboolean is_deleted = (camel_message_info_flags (looking_info) & CAMEL_MESSAGE_DELETED) != 0; + gboolean is_junk = (camel_message_info_flags (looking_info) & CAMEL_MESSAGE_JUNK) != 0; /* I would really like to check for CAMEL_MESSAGE_FOLDER_FLAGGED on a message, so I would know whether it was changed locally, and then just check the changes @@ -4064,7 +4065,7 @@ regen_list_exec (struct _regen_list_msg *m) matter. So here just check whether the file was deleted and we show it based on the flag whether we can view deleted messages or not. */ - if (!was_deleted || (was_deleted && !m->hidedel)) + if ((!is_deleted || (is_deleted && !m->hidedel)) && (!is_junk || (is_junk && !m->hidejunk))) g_ptr_array_add (uids, (gpointer) camel_pstring_strdup (looking_for)); camel_folder_free_message_info (m->folder, looking_info); -- cgit From e377ea5e61171e57f9e892652d0fd1f77953eda8 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 27 Apr 2009 14:53:18 -0400 Subject: Bug 516933 – Rewrite attachment UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite the attachment UI to better utilize GIO and also to migrate from GnomeIconList to GtkIconView. This also introduces a "List View" option similar to Nautilus, as well as the EAttachmentHandler framework for extending attachment handling (may eventually replace EMFormatHook). This commit also fixes a number of secondary attachment bugs: Bug 311609 – new attachment bar should use regular gtk+ expander Bug 314923 – Drag and Drop in attachment window is inconsistent and requires additional click Bug 338179 – attachment saving ... Bug 350364 – Action to get info about attachments Bug 383047 – Viewing mail attachments Bug 427235 – Can't copy attachment mime type string Bug 454091 – Cannot save multiple attachments who have the same name Bug 494629 – Rethink composer's attachment UI Bug 553970 – Evolution ignores umask when saving attachments Bug 577375 – mailto: and attach doesn't URL un-escape --- mail/e-attachment-handler-mail.c | 524 ++++++++++++++++++++++++++ mail/e-attachment-handler-mail.h | 65 ++++ mail/e-mail-attachment-bar.c | 770 +++++++++++++++++++++++++++++++++++++++ mail/e-mail-attachment-bar.h | 77 ++++ 4 files changed, 1436 insertions(+) create mode 100644 mail/e-attachment-handler-mail.c create mode 100644 mail/e-attachment-handler-mail.h create mode 100644 mail/e-mail-attachment-bar.c create mode 100644 mail/e-mail-attachment-bar.h (limited to 'mail') diff --git a/mail/e-attachment-handler-mail.c b/mail/e-attachment-handler-mail.c new file mode 100644 index 0000000000..df4c0a9e3e --- /dev/null +++ b/mail/e-attachment-handler-mail.c @@ -0,0 +1,524 @@ +/* + * e-attachment-handler-mail.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-attachment-handler-mail.h" + +#include +#include +#include + +#include "e-util/e-error.h" +#include "mail/em-composer-utils.h" +#include "mail/mail-tools.h" + +#define E_ATTACHMENT_HANDLER_MAIL_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailPrivate)) + +struct _EAttachmentHandlerMailPrivate { + gint placeholder; +}; + +static gpointer parent_class; + +static const gchar *ui = +"" +" " +" " +" " +" " +" " +" " +" " +""; + +/* Note: Do not use the info field. */ +static GtkTargetEntry target_table[] = { + { "message/rfc822", 0, 0 }, + { "x-uid-list", 0, 0 } +}; + +static void +attachment_handler_mail_forward (GtkAction *action, + EAttachmentView *view) +{ + EAttachment *attachment; + CamelMimePart *mime_part; + CamelDataWrapper *wrapper; + GList *selected; + + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + + attachment = E_ATTACHMENT (selected->data); + mime_part = e_attachment_get_mime_part (attachment); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + + em_utils_forward_message (CAMEL_MIME_MESSAGE (wrapper), NULL); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static void +attachment_handler_mail_reply_all (GtkAction *action, + EAttachmentView *view) +{ + EAttachment *attachment; + CamelMimePart *mime_part; + CamelDataWrapper *wrapper; + GList *selected; + + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + + attachment = E_ATTACHMENT (selected->data); + mime_part = e_attachment_get_mime_part (attachment); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + + em_utils_reply_to_message ( + NULL, NULL, CAMEL_MIME_MESSAGE (wrapper), + REPLY_MODE_ALL, NULL); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static void +attachment_handler_mail_reply_sender (GtkAction *action, + EAttachmentView *view) +{ + EAttachment *attachment; + CamelMimePart *mime_part; + CamelDataWrapper *wrapper; + GList *selected; + + selected = e_attachment_view_get_selected_attachments (view); + g_return_if_fail (g_list_length (selected) == 1); + + attachment = E_ATTACHMENT (selected->data); + mime_part = e_attachment_get_mime_part (attachment); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + + em_utils_reply_to_message ( + NULL, NULL, CAMEL_MIME_MESSAGE (wrapper), + REPLY_MODE_SENDER, NULL); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static GtkActionEntry standard_entries[] = { + + { "mail-forward", + "mail-forward", + N_("_Forward"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (attachment_handler_mail_forward) }, + + { "mail-reply-all", + "mail-reply-all", + N_("Reply to _All"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (attachment_handler_mail_reply_all) }, + + { "mail-reply-sender", + "mail-reply-sender", + N_("_Reply to Sender"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (attachment_handler_mail_reply_sender) } +}; + +static void +attachment_handler_mail_message_rfc822 (EAttachmentView *view, + GdkDragContext *drag_context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + static GdkAtom atom = GDK_NONE; + EAttachmentStore *store; + EAttachment *attachment; + CamelMimeMessage *message; + CamelDataWrapper *wrapper; + CamelStream *stream; + const gchar *data; + gboolean success = FALSE; + gpointer parent; + gint length; + + if (G_UNLIKELY (atom == GDK_NONE)) + atom = gdk_atom_intern_static_string ("message/rfc822"); + + if (gtk_selection_data_get_target (selection_data) != atom) + return; + + g_signal_stop_emission_by_name (view, "drag-data-received"); + + data = (const gchar *) gtk_selection_data_get_data (selection_data); + length = gtk_selection_data_get_length (selection_data); + + stream = camel_stream_mem_new (); + camel_stream_write (stream, data, length); + camel_stream_reset (stream); + + message = camel_mime_message_new (); + wrapper = CAMEL_DATA_WRAPPER (message); + + if (camel_data_wrapper_construct_from_stream (wrapper, stream) == -1) + goto exit; + + store = e_attachment_view_get_store (view); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + attachment = e_attachment_new_for_message (message); + e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); + g_object_unref (attachment); + + success = TRUE; + +exit: + camel_object_unref (message); + camel_object_unref (stream); + + gtk_drag_finish (drag_context, success, FALSE, time); +} + +static void +attachment_handler_mail_x_uid_list (EAttachmentView *view, + GdkDragContext *drag_context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + static GdkAtom atom = GDK_NONE; + CamelException ex = CAMEL_EXCEPTION_INITIALISER; + CamelDataWrapper *wrapper; + CamelMimeMessage *message; + CamelMultipart *multipart; + CamelMimePart *mime_part; + CamelFolder *folder = NULL; + EAttachment *attachment; + EAttachmentStore *store; + GPtrArray *uids; + const gchar *data; + const gchar *cp, *end; + gchar *description; + gpointer parent; + gint length; + guint ii; + + if (G_UNLIKELY (atom == GDK_NONE)) + atom = gdk_atom_intern_static_string ("x-uid-list"); + + if (gtk_selection_data_get_target (selection_data) != atom) + return; + + store = e_attachment_view_get_store (view); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (view)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; + + uids = g_ptr_array_new (); + + data = (const gchar *) gtk_selection_data_get_data (selection_data); + length = gtk_selection_data_get_length (selection_data); + + /* The UID list is delimited by NUL characters. + * Brilliant. So we can't use g_strsplit(). */ + + cp = data; + end = data + length; + + while (cp < end) { + const gchar *start = cp; + + while (cp < end && *cp != '\0') + cp++; + + /* Skip the first string. */ + if (start > data) + g_ptr_array_add (uids, g_strndup (start, cp - start)); + + cp++; + } + + if (uids->len == 0) + goto exit; + + /* The first string is the folder URI. */ + folder = mail_tool_uri_to_folder (data, 0, &ex); + if (folder == NULL) + goto exit; + + /* Handle one message. */ + if (uids->len == 1) { + message = camel_folder_get_message ( + folder, uids->pdata[0], &ex); + if (message == NULL) + goto exit; + + attachment = e_attachment_new_for_message (message); + e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); + g_object_unref (attachment); + + camel_object_unref (message); + goto exit; + } + + /* Build a multipart/digest message out of the UIDs. */ + + multipart = camel_multipart_new (); + wrapper = CAMEL_DATA_WRAPPER (multipart); + camel_data_wrapper_set_mime_type (wrapper, "multipart/digest"); + camel_multipart_set_boundary (multipart, NULL); + + for (ii = 0; ii < uids->len; ii++) { + message = camel_folder_get_message ( + folder, uids->pdata[ii], &ex); + if (message == NULL) { + camel_object_unref (multipart); + goto exit; + } + + mime_part = camel_mime_part_new (); + wrapper = CAMEL_DATA_WRAPPER (message); + camel_mime_part_set_disposition (mime_part, "inline"); + camel_medium_set_content_object ( + CAMEL_MEDIUM (mime_part), wrapper); + camel_mime_part_set_content_type (mime_part, "message/rfc822"); + camel_multipart_add_part (multipart, mime_part); + camel_object_unref (mime_part); + + camel_object_unref (message); + } + + mime_part = camel_mime_part_new (); + wrapper = CAMEL_DATA_WRAPPER (multipart); + camel_medium_set_content_object (CAMEL_MEDIUM (mime_part), wrapper); + + /* Translators: This is only for multiple messages. */ + description = g_strdup_printf (_("%d attached messages"), uids->len); + camel_mime_part_set_description (mime_part, description); + g_free (description); + + attachment = e_attachment_new (); + e_attachment_set_mime_part (attachment, mime_part); + e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); + g_object_unref (attachment); + + camel_object_unref (mime_part); + camel_object_unref (multipart); + +exit: + if (camel_exception_is_set (&ex)) { + gchar *folder_name; + + if (folder != NULL) + camel_object_get ( + folder, NULL, CAMEL_FOLDER_NAME, + &folder_name, NULL); + else + folder_name = g_strdup (data); + + e_error_run ( + parent, "mail-composer:attach-nomessages", + folder_name, camel_exception_get_description (&ex), + NULL); + + if (folder != NULL) + camel_object_free ( + folder, CAMEL_FOLDER_NAME, folder_name); + else + g_free (folder_name); + + camel_exception_clear (&ex); + } + + if (folder != NULL) + camel_object_unref (folder); + + g_ptr_array_free (uids, TRUE); + + g_signal_stop_emission_by_name (view, "drag-data-received"); +} + +static void +attachment_handler_mail_update_actions (EAttachmentView *view) +{ + EAttachment *attachment; + CamelMimePart *mime_part; + CamelDataWrapper *wrapper; + GtkActionGroup *action_group; + GList *selected; + gboolean visible = FALSE; + + selected = e_attachment_view_get_selected_attachments (view); + + if (g_list_length (selected) != 1) + goto exit; + + attachment = E_ATTACHMENT (selected->data); + mime_part = e_attachment_get_mime_part (attachment); + + if (!CAMEL_IS_MIME_PART (mime_part)) + goto exit; + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); + + visible = CAMEL_IS_MIME_MESSAGE (wrapper); + +exit: + action_group = e_attachment_view_get_action_group (view, "mail"); + gtk_action_group_set_visible (action_group, visible); + + g_list_foreach (selected, (GFunc) g_object_unref, NULL); + g_list_free (selected); +} + +static void +attachment_handler_mail_constructed (GObject *object) +{ + EAttachmentHandler *handler; + EAttachmentView *view; + GtkActionGroup *action_group; + GtkUIManager *ui_manager; + GError *error = NULL; + + handler = E_ATTACHMENT_HANDLER (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + view = e_attachment_handler_get_view (handler); + + action_group = e_attachment_view_add_action_group (view, "mail"); + gtk_action_group_add_actions ( + action_group, standard_entries, + G_N_ELEMENTS (standard_entries), view); + + ui_manager = e_attachment_view_get_ui_manager (view); + gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); + + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + g_signal_connect ( + view, "update-actions", + G_CALLBACK (attachment_handler_mail_update_actions), + NULL); + + g_signal_connect ( + view, "drag-data-received", + G_CALLBACK (attachment_handler_mail_message_rfc822), + NULL); + + g_signal_connect ( + view, "drag-data-received", + G_CALLBACK (attachment_handler_mail_x_uid_list), + NULL); +} + +static GdkDragAction +attachment_handler_mail_get_drag_actions (EAttachmentHandler *handler) +{ + return GDK_ACTION_COPY; +} + +static const GtkTargetEntry * +attachment_handler_mail_get_target_table (EAttachmentHandler *handler, + guint *n_targets) +{ + if (n_targets != NULL) + *n_targets = G_N_ELEMENTS (target_table); + + return target_table; +} + +static void +attachment_handler_mail_class_init (EAttachmentHandlerMailClass *class) +{ + GObjectClass *object_class; + EAttachmentHandlerClass *handler_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentHandlerMailPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = attachment_handler_mail_constructed; + + handler_class = E_ATTACHMENT_HANDLER_CLASS (class); + handler_class->get_drag_actions = attachment_handler_mail_get_drag_actions; + handler_class->get_target_table = attachment_handler_mail_get_target_table; +} + +static void +attachment_handler_mail_init (EAttachmentHandlerMail *handler) +{ + handler->priv = E_ATTACHMENT_HANDLER_MAIL_GET_PRIVATE (handler); +} + +GType +e_attachment_handler_mail_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAttachmentHandlerMailClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_handler_mail_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAttachmentHandlerMail), + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_handler_mail_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_ATTACHMENT_HANDLER, + "EAttachmentHandlerMail", &type_info, 0); + } + + return type; +} diff --git a/mail/e-attachment-handler-mail.h b/mail/e-attachment-handler-mail.h new file mode 100644 index 0000000000..da4ff23d89 --- /dev/null +++ b/mail/e-attachment-handler-mail.h @@ -0,0 +1,65 @@ +/* + * e-attachment-handler-mail.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_ATTACHMENT_HANDLER_MAIL_H +#define E_ATTACHMENT_HANDLER_MAIL_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_ATTACHMENT_HANDLER_MAIL \ + (e_attachment_handler_mail_get_type ()) +#define E_ATTACHMENT_HANDLER_MAIL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMail)) +#define E_ATTACHMENT_HANDLER_MAIL_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailClass)) +#define E_IS_ATTACHMENT_HANDLER_MAIL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL)) +#define E_IS_ATTACHMENT_HANDLER_MAIL_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ATTACHMENT_HANDLER_MAIL)) +#define E_ATTACHMENT_HANDLER_MAIL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailClass)) + +G_BEGIN_DECLS + +typedef struct _EAttachmentHandlerMail EAttachmentHandlerMail; +typedef struct _EAttachmentHandlerMailClass EAttachmentHandlerMailClass; +typedef struct _EAttachmentHandlerMailPrivate EAttachmentHandlerMailPrivate; + +struct _EAttachmentHandlerMail { + EAttachmentHandler parent; + EAttachmentHandlerMailPrivate *priv; +}; + +struct _EAttachmentHandlerMailClass { + EAttachmentHandlerClass parent_class; +}; + +GType e_attachment_handler_mail_get_type (void); + +G_END_DECLS + +#endif /* E_ATTACHMENT_HANDLER_MAIL_H */ diff --git a/mail/e-mail-attachment-bar.c b/mail/e-mail-attachment-bar.c new file mode 100644 index 0000000000..d3432ca9cd --- /dev/null +++ b/mail/e-mail-attachment-bar.c @@ -0,0 +1,770 @@ +/* + * e-mail-attachment-bar.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-mail-attachment-bar.h" + +#include + +#include "e-util/e-binding.h" +#include "e-util/gconf-bridge.h" + +#include "e-attachment-store.h" +#include "e-attachment-icon-view.h" +#include "e-attachment-tree-view.h" + +#define E_MAIL_ATTACHMENT_BAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MAIL_ATTACHMENT_BAR, EMailAttachmentBarPrivate)) + +#define NUM_VIEWS 2 + +struct _EMailAttachmentBarPrivate { + GtkTreeModel *model; + GtkWidget *vbox; + GtkWidget *expander; + GtkWidget *combo_box; + GtkWidget *icon_view; + GtkWidget *tree_view; + GtkWidget *icon_frame; + GtkWidget *tree_frame; + GtkWidget *status_icon; + GtkWidget *status_label; + GtkWidget *save_all_button; + GtkWidget *save_one_button; + + gint active_view; + guint expanded : 1; +}; + +enum { + PROP_0, + PROP_ACTIVE_VIEW, + PROP_EDITABLE, + PROP_EXPANDED +}; + +static gpointer parent_class; + +static void +mail_attachment_bar_sync_icon_view (EMailAttachmentBar *bar) +{ + EAttachmentView *source; + EAttachmentView *target; + + source = E_ATTACHMENT_VIEW (bar->priv->tree_view); + target = E_ATTACHMENT_VIEW (bar->priv->icon_view); + + /* Only sync if the tree view is active. This prevents the + * two views from endlessly trying to sync with each other. */ + if (e_mail_attachment_bar_get_active_view (bar) == 1) + e_attachment_view_sync_selection (source, target); +} + +static void +mail_attachment_bar_sync_tree_view (EMailAttachmentBar *bar) +{ + EAttachmentView *source; + EAttachmentView *target; + + source = E_ATTACHMENT_VIEW (bar->priv->icon_view); + target = E_ATTACHMENT_VIEW (bar->priv->tree_view); + + /* Only sync if the icon view is active. This prevents the + * two views from endlessly trying to sync with each other. */ + if (e_mail_attachment_bar_get_active_view (bar) == 0) + e_attachment_view_sync_selection (source, target); +} + +static void +mail_attachment_bar_update_status (EMailAttachmentBar *bar) +{ + EAttachmentView *view; + EAttachmentStore *store; + GtkExpander *expander; + GtkAction *action; + GtkLabel *label; + gint num_attachments; + guint64 total_size; + gchar *display_size; + gchar *markup; + +#if GTK_CHECK_VERSION(2,16,0) + GtkActivatable *activatable; +#endif + + view = E_ATTACHMENT_VIEW (bar); + store = e_attachment_view_get_store (view); + expander = GTK_EXPANDER (bar->priv->expander); + label = GTK_LABEL (bar->priv->status_label); + + num_attachments = e_attachment_store_get_num_attachments (store); + total_size = e_attachment_store_get_total_size (store); + display_size = g_format_size_for_display (total_size); + + markup = g_strdup_printf ( + "%d %s (%s)", num_attachments, ngettext ( + "Attachment", "Attachments", num_attachments), + display_size); + gtk_label_set_markup (label, markup); + g_free (markup); + +#if GTK_CHECK_VERSION(2,16,0) + activatable = GTK_ACTIVATABLE (bar->priv->save_all_button); + action = gtk_activatable_get_related_action (activatable); +#else + action = e_attachment_view_get_action (view, "save-all"); +#endif + gtk_action_set_visible (action, (num_attachments > 1)); + +#if GTK_CHECK_VERSION(2,16,0) + activatable = GTK_ACTIVATABLE (bar->priv->save_one_button); + action = gtk_activatable_get_related_action (activatable); +#else + action = e_attachment_view_get_action (view, "save-one"); +#endif + gtk_action_set_visible (action, (num_attachments == 1)); + + g_free (display_size); +} + +static void +mail_attachment_bar_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTIVE_VIEW: + e_mail_attachment_bar_set_active_view ( + E_MAIL_ATTACHMENT_BAR (object), + g_value_get_int (value)); + return; + + case PROP_EDITABLE: + e_attachment_view_set_editable ( + E_ATTACHMENT_VIEW (object), + g_value_get_boolean (value)); + return; + + case PROP_EXPANDED: + e_mail_attachment_bar_set_expanded ( + E_MAIL_ATTACHMENT_BAR (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +mail_attachment_bar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ACTIVE_VIEW: + g_value_set_int ( + value, + e_mail_attachment_bar_get_active_view ( + E_MAIL_ATTACHMENT_BAR (object))); + return; + + case PROP_EDITABLE: + g_value_set_boolean ( + value, + e_attachment_view_get_editable ( + E_ATTACHMENT_VIEW (object))); + return; + + case PROP_EXPANDED: + g_value_set_boolean ( + value, + e_mail_attachment_bar_get_expanded ( + E_MAIL_ATTACHMENT_BAR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +mail_attachment_bar_dispose (GObject *object) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (object); + + if (priv->model != NULL) { + g_object_unref (priv->model); + priv->model = NULL; + } + + if (priv->vbox != NULL) { + g_object_unref (priv->vbox); + priv->vbox = NULL; + } + + if (priv->expander != NULL) { + g_object_unref (priv->expander); + priv->expander = NULL; + } + + if (priv->combo_box != NULL) { + g_object_unref (priv->combo_box); + priv->combo_box = NULL; + } + + if (priv->icon_view != NULL) { + g_object_unref (priv->icon_view); + priv->icon_view = NULL; + } + + if (priv->tree_view != NULL) { + g_object_unref (priv->tree_view); + priv->tree_view = NULL; + } + + if (priv->icon_frame != NULL) { + g_object_unref (priv->icon_frame); + priv->icon_frame = NULL; + } + + if (priv->tree_frame != NULL) { + g_object_unref (priv->tree_frame); + priv->tree_frame = NULL; + } + + if (priv->status_icon != NULL) { + g_object_unref (priv->status_icon); + priv->status_icon = NULL; + } + + if (priv->status_label != NULL) { + g_object_unref (priv->status_label); + priv->status_label = NULL; + } + + if (priv->save_all_button != NULL) { + g_object_unref (priv->save_all_button); + priv->save_all_button = NULL; + } + + if (priv->save_one_button != NULL) { + g_object_unref (priv->save_one_button); + priv->save_one_button = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +mail_attachment_bar_constructed (GObject *object) +{ + EMailAttachmentBarPrivate *priv; + GConfBridge *bridge; + const gchar *key; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (object); + + bridge = gconf_bridge_get (); + + /* Set up property-to-property bindings. */ + + e_mutual_binding_new ( + G_OBJECT (object), "active-view", + G_OBJECT (priv->combo_box), "active"); + + e_mutual_binding_new ( + G_OBJECT (object), "editable", + G_OBJECT (priv->icon_view), "editable"); + + e_mutual_binding_new ( + G_OBJECT (object), "editable", + G_OBJECT (priv->tree_view), "editable"); + + e_mutual_binding_new ( + G_OBJECT (object), "expanded", + G_OBJECT (priv->expander), "expanded"); + + e_mutual_binding_new ( + G_OBJECT (object), "expanded", + G_OBJECT (priv->combo_box), "visible"); + + e_mutual_binding_new ( + G_OBJECT (object), "expanded", + G_OBJECT (priv->vbox), "visible"); + + /* Set up property-to-GConf bindings. */ + + key = "/apps/evolution/shell/attachment_view"; + gconf_bridge_bind_property (bridge, key, object, "active-view"); +} + +static void +mail_attachment_bar_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + /* XXX This works around GtkHTMLEmbedded not taking visibility + * into account when calculating its size (at least I think + * that's where it's broken). Without the workaround, we + * get a sizable gap between the headers and body when this + * widget is invisible. Once we finally move to WebKit, + * remove this. */ + if (!GTK_WIDGET_VISIBLE (widget)) { + requisition->width = 0; + requisition->height = 0; + return; + } + + /* Chain up to parent's size_request() method. */ + GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition); +} + +static EAttachmentViewPrivate * +mail_attachment_bar_get_private (EAttachmentView *view) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_get_private (view); +} + +static EAttachmentStore * +mail_attachment_bar_get_store (EAttachmentView *view) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_get_store (view); +} + +static GtkTreePath * +mail_attachment_bar_get_path_at_pos (EAttachmentView *view, + gint x, + gint y) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_get_path_at_pos (view, x, y); +} + +static GList * +mail_attachment_bar_get_selected_paths (EAttachmentView *view) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_get_selected_paths (view); +} + +static gboolean +mail_attachment_bar_path_is_selected (EAttachmentView *view, + GtkTreePath *path) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + return e_attachment_view_path_is_selected (view, path); +} + +static void +mail_attachment_bar_select_path (EAttachmentView *view, + GtkTreePath *path) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_select_path (view, path); +} + +static void +mail_attachment_bar_unselect_path (EAttachmentView *view, + GtkTreePath *path) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_unselect_path (view, path); +} + +static void +mail_attachment_bar_select_all (EAttachmentView *view) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_select_all (view); +} + +static void +mail_attachment_bar_unselect_all (EAttachmentView *view) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_unselect_all (view); +} + +static void +mail_attachment_bar_update_actions (EAttachmentView *view) +{ + EMailAttachmentBarPrivate *priv; + + priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view); + view = E_ATTACHMENT_VIEW (priv->icon_view); + + e_attachment_view_update_actions (view); +} + +static void +mail_attachment_bar_class_init (EMailAttachmentBarClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMailAttachmentBarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = mail_attachment_bar_set_property; + object_class->get_property = mail_attachment_bar_get_property; + object_class->dispose = mail_attachment_bar_dispose; + object_class->constructed = mail_attachment_bar_constructed; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->size_request = mail_attachment_bar_size_request; + + g_object_class_install_property ( + object_class, + PROP_ACTIVE_VIEW, + g_param_spec_int ( + "active-view", + "Active View", + NULL, + 0, + NUM_VIEWS, + 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_EXPANDED, + g_param_spec_boolean ( + "expanded", + "Expanded", + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_override_property ( + object_class, PROP_EDITABLE, "editable"); +} + +static void +mail_attachment_bar_iface_init (EAttachmentViewIface *iface) +{ + iface->get_private = mail_attachment_bar_get_private; + iface->get_store = mail_attachment_bar_get_store; + iface->get_path_at_pos = mail_attachment_bar_get_path_at_pos; + iface->get_selected_paths = mail_attachment_bar_get_selected_paths; + iface->path_is_selected = mail_attachment_bar_path_is_selected; + iface->select_path = mail_attachment_bar_select_path; + iface->unselect_path = mail_attachment_bar_unselect_path; + iface->select_all = mail_attachment_bar_select_all; + iface->unselect_all = mail_attachment_bar_unselect_all; + iface->update_actions = mail_attachment_bar_update_actions; +} + +static void +mail_attachment_bar_init (EMailAttachmentBar *bar) +{ + EAttachmentView *view; + GtkTreeSelection *selection; + GtkSizeGroup *size_group; + GtkWidget *container; + GtkWidget *widget; + GtkAction *action; + + bar->priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (bar); + bar->priv->model = e_attachment_store_new (); + + gtk_box_set_spacing (GTK_BOX (bar), 6); + + /* Keep the expander label and save button the same height. */ + size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); + + /* Construct the Attachment Views */ + + container = GTK_WIDGET (bar); + + widget = gtk_vbox_new (FALSE, 0); + gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); + bar->priv->vbox = g_object_ref (widget); + gtk_widget_show (widget); + + container = bar->priv->vbox; + + widget = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + bar->priv->icon_frame = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = e_attachment_icon_view_new (); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); + gtk_icon_view_set_model (GTK_ICON_VIEW (widget), bar->priv->model); + gtk_container_add (GTK_CONTAINER (container), widget); + bar->priv->icon_view = g_object_ref (widget); + gtk_widget_show (widget); + + container = bar->priv->vbox; + + widget = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + bar->priv->tree_frame = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = e_attachment_tree_view_new (); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); + gtk_tree_view_set_model (GTK_TREE_VIEW (widget), bar->priv->model); + gtk_container_add (GTK_CONTAINER (container), widget); + bar->priv->tree_view = g_object_ref (widget); + gtk_widget_show (widget); + + /* Construct the Controls */ + + container = GTK_WIDGET (bar); + + widget = gtk_hbox_new (FALSE, 12); + gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_expander_new (NULL); + gtk_expander_set_spacing (GTK_EXPANDER (widget), 0); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + bar->priv->expander = g_object_ref (widget); + gtk_widget_show (widget); + + /* The "Save All" button proxies the "save-all" action from + * one of the two attachment views. Doesn't matter which. */ + widget = gtk_button_new (); + view = E_ATTACHMENT_VIEW (bar->priv->icon_view); + action = e_attachment_view_get_action (view, "save-all"); + gtk_button_set_image (GTK_BUTTON (widget), gtk_image_new ()); +#if GTK_CHECK_VERSION(2,16,0) + gtk_activatable_set_related_action (GTK_ACTIVATABLE (widget), action); +#else + gtk_action_connect_proxy (action, widget); /* XXX Deprecated */ +#endif + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + bar->priv->save_all_button = g_object_ref (widget); + gtk_widget_show (widget); + + /* Same deal with the "Save" button. */ + widget = gtk_button_new (); + view = E_ATTACHMENT_VIEW (bar->priv->icon_view); + action = e_attachment_view_get_action (view, "save-one"); + gtk_button_set_image (GTK_BUTTON (widget), gtk_image_new ()); +#if GTK_CHECK_VERSION(2,16,0) + gtk_activatable_set_related_action (GTK_ACTIVATABLE (widget), action); +#else + gtk_action_connect_proxy (action, widget); /* XXX Deprecated */ +#endif + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + bar->priv->save_one_button = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_alignment_new (1.0, 0.5, 0.0, 0.0); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_combo_box_new_text (); + gtk_size_group_add_widget (size_group, widget); + gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Icon View")); + gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("List View")); + gtk_container_add (GTK_CONTAINER (container), widget); + bar->priv->combo_box = g_object_ref (widget); + gtk_widget_show (widget); + + container = bar->priv->expander; + + widget = gtk_hbox_new (FALSE, 6); + gtk_size_group_add_widget (size_group, widget); + gtk_expander_set_label_widget (GTK_EXPANDER (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_image_new_from_icon_name ( + "mail-attachment", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + bar->priv->status_icon = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_label_new (NULL); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + bar->priv->status_label = g_object_ref (widget); + gtk_widget_show (widget); + + selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (bar->priv->tree_view)); + + g_signal_connect_swapped ( + selection, "changed", + G_CALLBACK (mail_attachment_bar_sync_icon_view), bar); + + g_signal_connect_swapped ( + bar->priv->icon_view, "selection-changed", + G_CALLBACK (mail_attachment_bar_sync_tree_view), bar); + + g_signal_connect_swapped ( + bar->priv->model, "notify::num-attachments", + G_CALLBACK (mail_attachment_bar_update_status), bar); + + g_signal_connect_swapped ( + bar->priv->model, "notify::total-size", + G_CALLBACK (mail_attachment_bar_update_status), bar); + + g_object_unref (size_group); +} + +GType +e_mail_attachment_bar_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EMailAttachmentBarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) mail_attachment_bar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMailAttachmentBar), + 0, /* n_preallocs */ + (GInstanceInitFunc) mail_attachment_bar_init, + NULL /* value_table */ + }; + + static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) mail_attachment_bar_iface_init, + (GInterfaceFinalizeFunc) NULL, + NULL /* interface_data */ + }; + + type = g_type_register_static ( + GTK_TYPE_VBOX, "EMailAttachmentBar", &type_info, 0); + + g_type_add_interface_static ( + type, E_TYPE_ATTACHMENT_VIEW, &iface_info); + } + + return type; +} + +GtkWidget * +e_mail_attachment_bar_new (void) +{ + return g_object_new ( + E_TYPE_MAIL_ATTACHMENT_BAR, + "editable", FALSE, NULL); +} + +gint +e_mail_attachment_bar_get_active_view (EMailAttachmentBar *bar) +{ + g_return_val_if_fail (E_IS_MAIL_ATTACHMENT_BAR (bar), 0); + + return bar->priv->active_view; +} + +void +e_mail_attachment_bar_set_active_view (EMailAttachmentBar *bar, + gint active_view) +{ + g_return_if_fail (E_IS_MAIL_ATTACHMENT_BAR (bar)); + g_return_if_fail (active_view >= 0 && active_view < NUM_VIEWS); + + bar->priv->active_view = active_view; + + if (active_view == 0) { + gtk_widget_show (bar->priv->icon_frame); + gtk_widget_hide (bar->priv->tree_frame); + } else { + gtk_widget_hide (bar->priv->icon_frame); + gtk_widget_show (bar->priv->tree_frame); + } + + g_object_notify (G_OBJECT (bar), "active-view"); +} + +gboolean +e_mail_attachment_bar_get_expanded (EMailAttachmentBar *bar) +{ + g_return_val_if_fail (E_IS_MAIL_ATTACHMENT_BAR (bar), FALSE); + + return bar->priv->expanded; +} + +void +e_mail_attachment_bar_set_expanded (EMailAttachmentBar *bar, + gboolean expanded) +{ + g_return_if_fail (E_IS_MAIL_ATTACHMENT_BAR (bar)); + + bar->priv->expanded = expanded; + + g_object_notify (G_OBJECT (bar), "expanded"); +} diff --git a/mail/e-mail-attachment-bar.h b/mail/e-mail-attachment-bar.h new file mode 100644 index 0000000000..e32f6e2ede --- /dev/null +++ b/mail/e-mail-attachment-bar.h @@ -0,0 +1,77 @@ +/* + * e-mail-attachment-bar.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_MAIL_ATTACHMENT_BAR_H +#define E_MAIL_ATTACHMENT_BAR_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_MAIL_ATTACHMENT_BAR \ + (e_mail_attachment_bar_get_type ()) +#define E_MAIL_ATTACHMENT_BAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MAIL_ATTACHMENT_BAR, EMailAttachmentBar)) +#define E_MAIL_ATTACHMENT_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MAIL_ATTACHMENT_BAR, EMailAttachmentBarClass)) +#define E_IS_MAIL_ATTACHMENT_BAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MAIL_ATTACHMENT_BAR)) +#define E_IS_MAIL_ATTACHMENT_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MAIL_ATTACHMENT_BAR)) +#define E_MAIL_ATTACHMENT_BAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MAIL_ATTACHMENT_BAR, EMailAttachmentBarClass)) + +G_BEGIN_DECLS + +typedef struct _EMailAttachmentBar EMailAttachmentBar; +typedef struct _EMailAttachmentBarClass EMailAttachmentBarClass; +typedef struct _EMailAttachmentBarPrivate EMailAttachmentBarPrivate; + +struct _EMailAttachmentBar { + GtkVBox parent; + EMailAttachmentBarPrivate *priv; +}; + +struct _EMailAttachmentBarClass { + GtkVBoxClass parent_class; +}; + +GType e_mail_attachment_bar_get_type (void); +GtkWidget * e_mail_attachment_bar_new (void); +gint e_mail_attachment_bar_get_active_view + (EMailAttachmentBar *bar); +void e_mail_attachment_bar_set_active_view + (EMailAttachmentBar *bar, + gint active_view); +gboolean e_mail_attachment_bar_get_expanded + (EMailAttachmentBar *bar); +void e_mail_attachment_bar_set_expanded + (EMailAttachmentBar *bar, + gboolean expanded); + +G_END_DECLS + +#endif /* E_MAIL_ATTACHMENT_BAR_H */ -- cgit From 4449a34101406bffe508dd40b8b653f7c7d14c7d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 27 Apr 2009 15:36:19 -0400 Subject: Commit the rest of the attachment UI rewrite Oops, last commit only included the -new- files. This also removes EExpander, which is no longer used. --- mail/Makefile.am | 4 + mail/em-filter-i18n.h | 2 + mail/em-format-html-display.c | 615 +++++++----------------------------------- mail/em-format-html-display.h | 2 - mail/em-popup.c | 123 +-------- mail/em-popup.h | 35 +-- mail/mail-component.c | 5 + 7 files changed, 123 insertions(+), 663 deletions(-) (limited to 'mail') diff --git a/mail/Makefile.am b/mail/Makefile.am index 23778d569c..2a567ec042 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -54,6 +54,7 @@ idl_DATA = $(MAIL_IDL) # plugin mail api mailinclude_HEADERS = \ $(MAIL_IDL_GENERATED_H) \ + e-mail-attachment-bar.h \ em-composer-utils.h \ em-config.h \ em-event.h \ @@ -93,6 +94,9 @@ mailinclude_HEADERS = \ libevolution_mail_la_SOURCES = \ $(MAIL_IDL_GENERATED) \ $(mailinclude_HEADERS) \ + e-attachment-handler-mail.c \ + e-attachment-handler-mail.h \ + e-mail-attachment-bar.c \ e-searching-tokenizer.c \ e-searching-tokenizer.h \ em-account-editor.c \ diff --git a/mail/em-filter-i18n.h b/mail/em-filter-i18n.h index 8b8d0c3323..c0b2925cc2 100644 --- a/mail/em-filter-i18n.h +++ b/mail/em-filter-i18n.h @@ -26,6 +26,7 @@ char *s = N_("Exist"); char *s = N_("exists"); char *s = N_("Expression"); char *s = N_("Follow Up"); +char *s = N_("Forward to"); char *s = N_("Important"); char *s = N_("is"); char *s = N_("is after"); @@ -46,6 +47,7 @@ char *s = N_("Message Body"); char *s = N_("Message Header"); char *s = N_("Message is Junk"); char *s = N_("Message is not Junk"); +char *s = N_("Message Location"); char *s = N_("Move to Folder"); char *s = N_("Pipe to Program"); char *s = N_("Play Sound"); diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c index ad72ee8bdd..789705879d 100644 --- a/mail/em-format-html-display.c +++ b/mail/em-format-html-display.c @@ -80,14 +80,15 @@ #include "mail-config.h" +#include "e-mail-attachment-bar.h" #include "em-format-html-display.h" #include "e-searching-tokenizer.h" #include "em-icon-stream.h" #include "em-utils.h" #include "em-popup.h" -#include "e-attachment.h" -#include "e-attachment-bar.h" #include "e-icon-entry.h" +#include "widgets/misc/e-attachment-button.h" +#include "widgets/misc/e-attachment-view.h" #ifdef G_OS_WIN32 /* Undefine the similar macro from ,it doesn't check if @@ -113,18 +114,7 @@ struct _EMFormatHTMLDisplayPrivate { int search_wrap; /* are we doing a wrap search */ gboolean search_active; /* if the search is active */ - /* for Attachment bar */ - GtkWidget *attachment_bar; - GtkWidget *attachment_box; - GtkWidget *label; - GtkWidget *save_txt; - GtkWidget *arrow; - GtkWidget *forward; - GtkWidget *down; - GtkWidget *attachment_area; - gboolean show_bar; - GHashTable *files; - gboolean updated; + GtkWidget *attachment_view; /* weak reference */ }; static int efhd_html_button_press_event (GtkWidget *widget, GdkEventButton *event, EMFormatHTMLDisplay *efh); @@ -134,8 +124,6 @@ static void efhd_html_on_url (GtkHTML *html, const char *url, EMFormatHTMLDispla static void efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri); static gboolean efhd_attachment_image(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject); static void efhd_message_add_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info); -static void efhd_message_update_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info); -static void efhd_attachment_bar_refresh (EMFormatHTMLDisplay *efhd); struct _attach_puri { EMFormatPURI puri; @@ -186,7 +174,6 @@ static void efhd_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, c static void efhd_format_optional(EMFormat *, CamelStream *, CamelMimePart *, CamelStream *); static void efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid); static void efhd_complete(EMFormat *); -gboolean efhd_mnemonic_show_bar (GtkWidget *widget, gboolean focus, GtkWidget *efhd); static gboolean efhd_bonobo_object(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject); static gboolean efhd_use_component(const char *mime_type); @@ -279,9 +266,6 @@ efhd_init(GObject *o) #undef efh efhd->nobar = getenv("EVOLUTION_NO_BAR") != NULL; - - efhd->priv->show_bar = FALSE; - efhd->priv->files = NULL; } static void @@ -291,9 +275,6 @@ efhd_finalise(GObject *o) /* check pending stuff */ - if (efhd->priv->files) - g_hash_table_destroy(efhd->priv->files); - g_free(efhd->priv->search_text); g_free(efhd->priv); @@ -431,12 +412,6 @@ void em_format_html_display_set_caret_mode(EMFormatHTMLDisplay *efhd, gboolean s gtk_html_set_caret_mode(((EMFormatHTML *)efhd)->html, state); } -EAttachmentBar * -em_format_html_display_get_bar (EMFormatHTMLDisplay *efhd) -{ - return E_ATTACHMENT_BAR (efhd->priv->attachment_bar); -} - void em_format_html_display_set_search(EMFormatHTMLDisplay *efhd, int type, GSList *strings) { @@ -933,11 +908,6 @@ efhd_complete(EMFormat *emf) if (efhd->priv->search_dialog && efhd->priv->search_active) efhd_update_matches(efhd); - - if (efhd->priv->files) { - g_hash_table_destroy (efhd->priv->files); - efhd->priv->files = NULL; - } } /* ********************************************************************** */ @@ -1293,9 +1263,7 @@ static EMFormatHandler type_builtin_table[] = { { "image/pjpeg", (EMFormatFunc)efhd_image }, { "x-evolution/message/prefix", (EMFormatFunc)efhd_message_prefix }, - { "x-evolution/message/post-header", (EMFormatFunc)efhd_message_add_bar }, - { "x-evolution/message/post-header-closure", (EMFormatFunc)efhd_message_update_bar }, - + { "x-evolution/message/post-header", (EMFormatFunc)efhd_message_add_bar } }; static void @@ -1343,15 +1311,8 @@ static const EMFormatHandler *efhd_find_handler(EMFormat *emf, const char *mime_ static void efhd_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *src) { - EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) emf; - - if (emf != src) { - if (src) - efhd->priv->show_bar = ((EMFormatHTMLDisplay *)src)->priv->show_bar; - else - efhd->priv->show_bar = FALSE; + if (emf != src) ((EMFormatHTML *) emf)->header_wrap_flags = 0; - } ((EMFormatClass *)efhd_parent)->format_clone(emf, folder, uid, msg, src); } @@ -1467,12 +1428,14 @@ efhd_attachment_show(EPopup *ep, EPopupItem *item, void *data) } static void -efhd_attachment_button_show(GtkWidget *w, void *data) +efhd_attachment_button_expanded (GtkWidget *widget, + GParamSpec *pspec, + struct _attach_puri *info) { - if (!efhd_can_process_attachment (w)) + if (!efhd_can_process_attachment (widget)) return; - efhd_attachment_show(NULL, NULL, data); + efhd_attachment_show (NULL, NULL, info); } static void @@ -1811,16 +1774,12 @@ static gboolean efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject) { EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)efh; - EAttachment *new; struct _attach_puri *info; - GtkWidget *hbox, *w, *button, *mainbox; - char *simple_type, *tmp, *new_file = NULL; - const char *file; - GtkTargetEntry drag_types[] = { - { NULL, 0, 0 }, - { "text/uri-list", 0, 1 }, - }; - AtkObject *a11y; + EAttachmentView *view; + EAttachmentStore *store; + EAttachment *attachment; + GtkWidget *widget; + gpointer parent; /* FIXME: handle default shown case */ d(printf("adding attachment button/content\n")); @@ -1832,139 +1791,36 @@ efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje return TRUE; } - if (efhd->priv->attachment_bar) { - file = camel_mime_part_get_filename(info->puri.part); - - new = info->attachment; - - if (!file) { - file = "attachment.dat"; - new->file_name = g_strdup(file); - } - - tmp = g_hash_table_lookup (efhd->priv->files, file); - if (tmp) { - guint count = GPOINTER_TO_UINT(tmp); - char *ext; - char *tmp_file = g_strdup (file); - - if ((ext = strrchr(tmp_file, '.'))) { - ext[0] = 0; - new_file = g_strdup_printf("%s(%d).%s", tmp_file, count++, ext+1); - } else { - new_file = g_strdup_printf("%s(%d)", tmp_file, count++); - } - - g_free (tmp_file); - g_hash_table_insert (efhd->priv->files, g_strdup(file), GUINT_TO_POINTER(count)); - g_free (new->file_name); - new->file_name = new_file; - } else { - g_hash_table_insert (efhd->priv->files, g_strdup(file), GUINT_TO_POINTER(1)); - } - - /* Store the status of encryption / signature on the attachment for emblem display - * FIXME: May not work well always - */ - new->sign = info->sign; - new->encrypt = info->encrypt; - - /* Add the attachment to the bar.*/ - e_attachment_bar_add_attachment_silent (E_ATTACHMENT_BAR(efhd->priv->attachment_bar), new); - efhd_attachment_bar_refresh(efhd); - } - - mainbox = gtk_hbox_new(FALSE, 0); - - button = gtk_button_new(); - - if (info->handle) { - g_signal_connect(button, "clicked", G_CALLBACK(efhd_attachment_button_show), info); - g_object_set_data (G_OBJECT (button), "efh", efh); - } else { - gtk_widget_set_sensitive(button, FALSE); - GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_FOCUS); - } - - hbox = gtk_hbox_new(FALSE, 2); - info->forward = gtk_image_new_from_stock(GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_BUTTON); - gtk_box_pack_start((GtkBox *)hbox, info->forward, TRUE, TRUE, 0); - if (info->handle) { - info->down = gtk_image_new_from_stock(GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_BUTTON); - gtk_box_pack_start((GtkBox *)hbox, info->down, TRUE, TRUE, 0); - } - - w = gtk_image_new(); - gtk_widget_set_size_request(w, 24, 24); - gtk_box_pack_start((GtkBox *)hbox, w, TRUE, TRUE, 0); - gtk_container_add((GtkContainer *)button, hbox); - gtk_box_pack_start((GtkBox *)mainbox, button, TRUE, TRUE, 0); - - /* Check for snooped type to get the right icon/processing */ - if (info->snoop_mime_type) - simple_type = g_strdup(info->snoop_mime_type); - else - simple_type = camel_content_type_simple (((CamelDataWrapper *)pobject->part)->mime_type); - camel_strdown(simple_type); - - /* FIXME: offline parts, just get icon */ - if (camel_content_type_is(((CamelDataWrapper *)pobject->part)->mime_type, "image", "*")) { - EMFormatHTMLJob *job; - GdkPixbuf *mini; - char *key; - - key = pobject->classid; - mini = em_icon_stream_get_image(key, 24, 24); - if (mini) { - d(printf("got image from cache '%s'\n", key)); - gtk_image_set_from_pixbuf((GtkImage *)w, mini); - g_object_unref(mini); - } else { - d(printf("need to create icon image '%s'\n", key)); - job = em_format_html_job_new(efh, efhd_write_icon_job, pobject); - job->stream = (CamelStream *)em_icon_stream_new((GtkImage *)w, key, 24, 24, FALSE); - em_format_html_job_queue(efh, job); - } - } else { - GdkPixbuf *pixbuf, *mini; - - if ((pixbuf = e_icon_for_mime_type (simple_type, 24))) { - if ((mini = e_icon_factory_pixbuf_scale (pixbuf, 24, 24))) { - gtk_image_set_from_pixbuf ((GtkImage *) w, mini); - g_object_unref (mini); - } - g_object_unref (pixbuf); - } - } - - drag_types[0].target = simple_type; - gtk_drag_source_set(button, GDK_BUTTON1_MASK, drag_types, sizeof(drag_types)/sizeof(drag_types[0]), GDK_ACTION_COPY); - g_signal_connect(button, "drag-data-get", G_CALLBACK(efhd_drag_data_get), pobject); - g_signal_connect (button, "drag-data-delete", G_CALLBACK(efhd_drag_data_delete), pobject); - g_free(simple_type); + attachment = info->attachment; + e_attachment_set_shown (attachment, info->shown); + e_attachment_set_signed (attachment, info->sign); + e_attachment_set_encrypted (attachment, info->encrypt); + e_attachment_set_can_show (attachment, info->handle != NULL); - button = gtk_button_new(); - /*GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_FOCUS);*/ - gtk_container_add((GtkContainer *)button, gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE)); + parent = gtk_widget_get_toplevel (GTK_WIDGET (efh->html)); + parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL; - a11y = gtk_widget_get_accessible (button); - atk_object_set_name (a11y, _("Attachment")); + view = E_ATTACHMENT_VIEW (efhd->priv->attachment_view); + gtk_widget_show (efhd->priv->attachment_view); - g_signal_connect(button, "button_press_event", G_CALLBACK(efhd_attachment_popup), info); - g_signal_connect(button, "popup_menu", G_CALLBACK(efhd_attachment_popup_menu), info); - g_signal_connect(button, "clicked", G_CALLBACK(efhd_attachment_popup_menu), info); - gtk_box_pack_start((GtkBox *)mainbox, button, TRUE, TRUE, 0); + store = e_attachment_view_get_store (view); + e_attachment_store_add_attachment (store, info->attachment); - g_object_set_data (G_OBJECT (button), "efh", efh); + e_attachment_load_async ( + info->attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, parent); - gtk_widget_show_all(mainbox); + widget = e_attachment_button_new (view); + e_attachment_button_set_attachment ( + E_ATTACHMENT_BUTTON (widget), attachment); + gtk_container_add (GTK_CONTAINER (eb), widget); + gtk_widget_show (widget); - if (info->shown) - gtk_widget_hide(info->forward); - else if (info->down) - gtk_widget_hide(info->down); + g_object_set_data (G_OBJECT (widget), "efh", efh); - gtk_container_add((GtkContainer *)eb, mainbox); + g_signal_connect ( + widget, "notify::expanded", + G_CALLBACK (efhd_attachment_button_expanded), info); return TRUE; } @@ -2138,330 +1994,57 @@ type_ok: } static void -attachment_bar_arrow_clicked(GtkWidget *w, EMFormatHTMLDisplay *efhd) +efhd_bar_resize (EMFormatHTML *efh, + GtkAllocation *event) { + EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) efh; + GtkWidget *widget; + gint width; - efhd->priv->show_bar = !efhd->priv->show_bar; + widget = GTK_WIDGET (efh->html); + width = widget->allocation.width - 12; - if (efhd->priv->show_bar) { - gtk_widget_show(efhd->priv->attachment_box); - gtk_widget_show(efhd->priv->down); - gtk_widget_hide(efhd->priv->forward); - } else { - gtk_widget_hide(efhd->priv->attachment_box); - gtk_widget_show(efhd->priv->forward); - gtk_widget_hide(efhd->priv->down); + if (width > 0) { + widget = efhd->priv->attachment_view; + gtk_widget_set_size_request (widget, width, -1); } } -static void -attachments_save_all_clicked (GtkWidget *widget, EMFormatHTMLDisplay *efhd) -{ - GSList *attachment_parts; - guint n_attachment_parts; - - attachment_parts = e_attachment_bar_get_parts ( - E_ATTACHMENT_BAR (efhd->priv->attachment_bar)); - n_attachment_parts = g_slist_length (attachment_parts); - g_return_if_fail (n_attachment_parts > 0); - - if (n_attachment_parts == 1) - em_utils_save_part ( - widget, _("Save attachment as"), - attachment_parts->data); - else - em_utils_save_parts ( - widget, _("Select folder to save all attachments"), - attachment_parts); - - g_slist_free (attachment_parts); -} - -static void -efhd_bar_popup_position(GtkMenu *menu, int *x, int *y, gboolean *push_in, gpointer user_data) -{ - EAttachmentBar *bar = user_data; - GnomeIconList *icon_list = user_data; - GList *selection; - GnomeCanvasPixbuf *image; - - gdk_window_get_origin (((GtkWidget*) bar)->window, x, y); - - selection = gnome_icon_list_get_selection (icon_list); - if (selection == NULL) - return; - - image = gnome_icon_list_get_icon_pixbuf_item (icon_list, GPOINTER_TO_INT(selection->data)); - if (image == NULL) - return; - - /* Put menu to the center of icon. */ - *x += (int)(image->item.x1 + image->item.x2) / 2; - *y += (int)(image->item.y1 + image->item.y2) / 2; -} - -static void -efhd_bar_save_selected(EPopup *ep, EPopupItem *item, void *data) -{ - EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)data; - GSList *attachment_parts, *tmp; - GSList *parts = NULL; - - attachment_parts = e_attachment_bar_get_selected(E_ATTACHMENT_BAR(efhd->priv->attachment_bar)); - - for (tmp = attachment_parts; tmp; tmp=tmp->next) - parts = g_slist_prepend(parts, ((EAttachment *)tmp->data)->body); - - parts = g_slist_reverse(parts); - em_utils_save_parts(efhd->priv->attachment_bar, _("Select folder to save selected attachments..."), parts); - g_slist_free (parts); - - g_slist_foreach(attachment_parts, (GFunc)g_object_unref, NULL); - g_slist_free (attachment_parts); -} - -static EPopupItem efhd_bar_menu_items[] = { - { E_POPUP_BAR, "05.display", }, - { E_POPUP_ITEM, "05.display.01", N_("_Save Selected..."), efhd_bar_save_selected, NULL, NULL, EM_POPUP_ATTACHMENTS_MULTIPLE}, -}; - -static gboolean -efhd_bar_button_press_event(EAttachmentBar *bar, GdkEventButton *event, EMFormat *emf) -{ - GtkMenu *menu; - GSList *list=NULL; - EPopupTarget *target; - EMPopup *emp; - GSList *menus = NULL; - int i; - - if (event && event->button != 3) - return FALSE; - - /** @HookPoint-EMPopup: Attachment Bar Context Menu - * @Id: org.gnome.evolution.mail.attachments.popup - * @Class: org.gnome.evolution.mail.popup:1.0 - * @Target: EMPopupTargetPart - * - * This is the drop-down menu shown when a user clicks on the attachment bar - * when attachments are selected. - */ - emp = em_popup_new("org.gnome.evolution.mail.attachments.popup"); - - /* Add something like save-selected, foward selected attachments in a mail etc....*/ - list = e_attachment_bar_get_selected(bar); - - /* Lets not propagate any more the r-click which is intended to us*/ - if ( g_slist_length (list) == 0) - return TRUE; - - target = (EPopupTarget *)em_popup_target_new_attachments(emp, list); - for (i=0; i<2; i++) - menus = g_slist_prepend(menus, &efhd_bar_menu_items[i]); - e_popup_add_items((EPopup *)emp, menus, NULL, efhd_menu_items_free, emf); - - ((EMPopupTargetPart *)target)->target.widget = (GtkWidget *)bar; - menu = e_popup_create_menu_once((EPopup *)emp, (EPopupTarget *)target, 0); - if (event) - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button, event->time); - else - gtk_menu_popup(menu, NULL, NULL, (GtkMenuPositionFunc)efhd_bar_popup_position, bar, 0, gtk_get_current_event_time()); - - return TRUE; -} - static gboolean -efhd_bar_popup_menu_event (EAttachmentBar *bar, EMFormat *emf) -{ - return efhd_bar_button_press_event(bar, NULL, emf); -} - -static void -efhd_attachment_bar_refresh (EMFormatHTMLDisplay *efhd) -{ - int nattachments; - - if (!efhd->priv->attachment_bar) - return; - - nattachments = e_attachment_bar_get_num_attachments (E_ATTACHMENT_BAR(efhd->priv->attachment_bar)); - if (nattachments) { - char *txt; - - /* Cant i put in the number of attachments here ?*/ - txt = g_strdup_printf(ngettext("%d at_tachment", "%d at_tachments", nattachments), nattachments); - gtk_label_set_text_with_mnemonic ((GtkLabel *)efhd->priv->label, txt); - g_free (txt); - - /* Show the bar even when the first attachment is added */ - if (nattachments == 1) { - gtk_widget_show_all (efhd->priv->attachment_area); - gtk_label_set_text_with_mnemonic ((GtkLabel *)efhd->priv->save_txt, _("S_ave")); - - if (efhd->priv->show_bar) { - gtk_widget_show(efhd->priv->down); - gtk_widget_hide(efhd->priv->forward); - } else { - gtk_widget_show(efhd->priv->forward); - gtk_widget_hide(efhd->priv->down); - gtk_widget_hide(efhd->priv->attachment_box); - } - } else if (nattachments > 1) { - gtk_label_set_text_with_mnemonic ((GtkLabel *)efhd->priv->save_txt, _("S_ave All")); - } - } -} - -static void -efhd_bar_resize(GtkWidget *w, GtkAllocation *event, EMFormatHTML *efh) +efhd_add_bar (EMFormatHTML *efh, + GtkHTMLEmbedded *eb, + EMFormatHTMLPObject *pobject) { - int width; - GtkRequisition req; EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) efh; + GtkWidget *widget; - gtk_widget_size_request (efhd->priv->attachment_bar, &req); - width = ((GtkWidget *) efh->html)->allocation.width - 16; - - /* Update the width of the bar when the width is greater than 1*/ - if (width > 0) - e_attachment_bar_set_width(E_ATTACHMENT_BAR(efhd->priv->attachment_bar), width); -} - -static gboolean -efhd_bar_scroll_event(GtkWidget *w, GdkEventScroll *event, EMFormatHTMLDisplay *efhd) -{ - gboolean ret; - - /* Emulate the scroll over the attachment bar, as if it is scrolled in the window. - * It doesnt go automatically since the GnomeIconList is a layout by itself - */ - g_signal_emit_by_name (gtk_widget_get_parent((GtkWidget *)efhd->formathtml.html), "scroll_event", event, &ret); - - return TRUE; -} - -gboolean -efhd_mnemonic_show_bar (GtkWidget *widget, gboolean focus, GtkWidget *efhd) -{ - attachment_bar_arrow_clicked (NULL, (EMFormatHTMLDisplay *)efhd); - - return TRUE; -} - -static gboolean -efhd_update_bar(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject) -{ - EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)efh; - struct _EMFormatHTMLDisplayPrivate *priv = efhd->priv; - - if (priv->attachment_bar) - e_attachment_bar_refresh (E_ATTACHMENT_BAR (priv->attachment_bar)); - - return TRUE; -} - -static gboolean -efhd_add_bar(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject) -{ - EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)efh; - struct _EMFormatHTMLDisplayPrivate *priv = efhd->priv; - GtkWidget *hbox1, *hbox2, *hbox3, *vbox, *txt, *image, *save, *scroll; - int width, height, bar_width; - - priv->attachment_bar = e_attachment_bar_new(NULL); - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - ((EAttachmentBar *)priv->attachment_bar)->expand = TRUE; - - priv->forward = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - priv->down = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE); - hbox3 = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start ((GtkBox *)hbox3, priv->forward, FALSE, FALSE, 0); - gtk_box_pack_start ((GtkBox *)hbox3, priv->down, FALSE, FALSE, 0); - priv->arrow = (GtkWidget *)gtk_tool_button_new(hbox3, NULL); - g_signal_connect (priv->arrow, "mnemonic_activate", G_CALLBACK (efhd_mnemonic_show_bar), efh); - atk_object_set_name (gtk_widget_get_accessible (priv->arrow), _("Show Attachments")); - - priv->label = gtk_label_new(_("No Attachment")); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->label), priv->arrow); - save = gtk_button_new(); - image = gtk_image_new_from_stock ("gtk-save", GTK_ICON_SIZE_BUTTON); - txt = gtk_label_new_with_mnemonic(_("S_ave")); - priv->save_txt = txt; - hbox1 = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start((GtkBox *)hbox1, image, FALSE, FALSE, 2); - gtk_box_pack_start((GtkBox *)hbox1, txt, FALSE, FALSE, 0); - - gtk_container_add((GtkContainer *)save, hbox1); - - hbox2 = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start ((GtkBox *)hbox2, priv->arrow, FALSE, FALSE, 0); - gtk_box_pack_start ((GtkBox *)hbox2, priv->label, FALSE, FALSE, 2); - gtk_box_pack_start ((GtkBox *)hbox2, save, FALSE, FALSE, 2); - - priv->attachment_box = scroll; - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); - gtk_container_add ((GtkContainer *)priv->attachment_box, priv->attachment_bar); - - gtk_widget_get_size_request(priv->attachment_bar, &width, &height); - - /* FIXME: What if the text is more?. Should we reduce the text with appending ...? - * or resize the bar? How to figure out that, it needs more space? */ - bar_width = ((GtkWidget *)efh->html)->parent->allocation.width - /* FIXME */16; - gtk_widget_set_size_request (priv->attachment_bar, - bar_width > 0 ? bar_width : 0, - 84 /* FIXME: Default show only one row, Dont hardcode size*/); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start ((GtkBox *)vbox, hbox2, FALSE, FALSE, 2); - gtk_box_pack_start ((GtkBox *)vbox, priv->attachment_box, TRUE, TRUE, 2); - - gtk_container_add ((GtkContainer *)eb, vbox); - gtk_widget_show ((GtkWidget *)eb); - - /* Lets hide it by default and show only when there are attachments */ - priv->attachment_area = vbox; - gtk_widget_hide_all (priv->attachment_area); + widget = e_mail_attachment_bar_new (); + gtk_container_add (GTK_CONTAINER (eb), widget); + efhd->priv->attachment_view = widget; + gtk_widget_hide (widget); - g_signal_connect (priv->arrow, "clicked", G_CALLBACK(attachment_bar_arrow_clicked), efh); - g_signal_connect (priv->attachment_bar, "button_press_event", G_CALLBACK(efhd_bar_button_press_event), efhd); - g_signal_connect (priv->attachment_bar, "popup-menu", G_CALLBACK(efhd_bar_popup_menu_event), efhd); - g_signal_connect (save, "clicked", G_CALLBACK(attachments_save_all_clicked), efh); - g_signal_connect (eb, "size_allocate", G_CALLBACK (efhd_bar_resize), efh); - g_signal_connect (priv->attachment_bar, "scroll_event", G_CALLBACK(efhd_bar_scroll_event), efhd); + g_signal_connect_swapped ( + eb, "size-allocate", + G_CALLBACK (efhd_bar_resize), efh); return TRUE; } -static void -efhd_message_update_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) emf; - const char *classid = "attachment-bar-refresh"; - - if (efhd->nobar || efhd->priv->updated) - return; - - efhd->priv->files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - efhd->priv->updated = TRUE; - em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_update_bar); - camel_stream_printf(stream, "", classid); - -} static void -efhd_message_add_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) +efhd_message_add_bar (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part, + const EMFormatHandler *info) { - EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) emf; const char *classid = "attachment-bar"; - if (efhd->nobar || efhd->priv->files) - return; + em_format_html_add_pobject ( + (EMFormatHTML *) emf, + sizeof (EMFormatHTMLPObject), + classid, part, efhd_add_bar); - efhd->priv->files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - efhd->priv->updated = FALSE; - - em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_add_bar); - camel_stream_printf(stream, "", classid); + camel_stream_printf ( + stream, "", classid); } static void @@ -2470,43 +2053,50 @@ efhd_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part, char *classid, *text, *html; struct _attach_puri *info; - classid = g_strdup_printf("attachment%s", emf->part_id->str); - info = (struct _attach_puri *)em_format_add_puri(emf, sizeof(*info), classid, part, efhd_attachment_frame); - em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_attachment_button); + classid = g_strdup_printf ("attachment%s", emf->part_id->str); + info = (struct _attach_puri *)em_format_add_puri ( + emf, sizeof (*info), classid, part, efhd_attachment_frame); + em_format_html_add_pobject ( + (EMFormatHTML *) emf, sizeof (EMFormatHTMLPObject), + classid, part, efhd_attachment_button); info->handle = handle; - info->shown = em_format_is_inline(emf, info->puri.part_id, info->puri.part, handle); + info->shown = em_format_is_inline ( + emf, info->puri.part_id, info->puri.part, handle); info->snoop_mime_type = emf->snoop_mime_type; - info->attachment = e_attachment_new_from_mime_part (info->puri.part); - e_attachment_bar_create_attachment_cache (info->attachment); + info->attachment = e_attachment_new (); + e_attachment_set_mime_part (info->attachment, info->puri.part); if (emf->valid) { info->sign = emf->valid->sign.status; info->encrypt = emf->valid->encrypt.status; } - camel_stream_write_string(stream, - EM_FORMAT_HTML_VPAD - ""); + camel_stream_write_string ( + stream, EM_FORMAT_HTML_VPAD + "
" - "" - "
"); - camel_stream_printf(stream, "", classid); + camel_stream_printf ( + stream, "", classid); - camel_stream_write_string(stream, - "
" + "" + "
" - "
"); + camel_stream_write_string ( + stream, "" + "
"); /* output some info about it */ /* FIXME: should we look up mime_type from object again? */ - text = em_format_describe_part(part, mime_type); - html = camel_text_to_html(text, ((EMFormatHTML *)emf)->text_html_flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0); - camel_stream_write_string(stream, html); - g_free(html); - g_free(text); - - camel_stream_write_string(stream, - "
\n" - EM_FORMAT_HTML_VPAD); + text = em_format_describe_part (part, mime_type); + html = camel_text_to_html ( + text, ((EMFormatHTML *)emf)->text_html_flags & + CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0); + camel_stream_write_string (stream, html); + g_free (html); + g_free (text); + + camel_stream_write_string ( + stream, "\n" + EM_FORMAT_HTML_VPAD); if (handle) { if (info->shown) @@ -2653,7 +2243,8 @@ efhd_format_optional(EMFormat *emf, CamelStream *fstream, CamelMimePart *part, C info->handle = em_format_find_handler(emf, "text/plain"); info->shown = FALSE; info->snoop_mime_type = "text/plain"; - info->attachment = e_attachment_new_from_mime_part (info->puri.part); + info->attachment = e_attachment_new (); + e_attachment_set_mime_part (info->attachment, info->puri.part); info->mstream = (CamelStreamMem *)mstream; if (emf->valid) { info->sign = emf->valid->sign.status; diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h index 651b981364..4e2e7c1f83 100644 --- a/mail/em-format-html-display.h +++ b/mail/em-format-html-display.h @@ -26,7 +26,6 @@ #define _EM_FORMAT_HTML_DISPLAY_H #include "mail/em-format-html.h" -#include "widgets/misc/e-attachment-bar.h" typedef struct _EMFormatHTMLDisplay EMFormatHTMLDisplay; typedef struct _EMFormatHTMLDisplayClass EMFormatHTMLDisplayClass; @@ -82,7 +81,6 @@ void em_format_html_display_paste (EMFormatHTMLDisplay *efhd); void em_format_html_display_zoom_in (EMFormatHTMLDisplay *efhd); void em_format_html_display_zoom_out (EMFormatHTMLDisplay *efhd); void em_format_html_display_zoom_reset (EMFormatHTMLDisplay *efhd); -EAttachmentBar *em_format_html_display_get_bar (EMFormatHTMLDisplay *efhd); gboolean em_format_html_display_popup_menu (EMFormatHTMLDisplay *efhd); diff --git a/mail/em-popup.c b/mail/em-popup.c index 91e6ed6280..debad8cb56 100644 --- a/mail/em-popup.c +++ b/mail/em-popup.c @@ -100,12 +100,6 @@ emp_target_free(EPopup *ep, EPopupTarget *t) g_free(s->uri); break; } - case EM_POPUP_TARGET_ATTACHMENTS: { - EMPopupTargetAttachments *s = (EMPopupTargetAttachments *)t; - - g_slist_foreach(s->attachments, (GFunc)g_object_unref, NULL); - g_slist_free(s->attachments); - break; } } ((EPopupClass *)emp_parent)->target_free(ep, t); @@ -361,42 +355,6 @@ done: return t; } -/** - * em_popup_target_new_attachments: - * @emp: - * @attachments: A list of EMsgComposerAttachment objects, reffed for - * the list. Will be unreff'd once finished with. - * - * Owns the list @attachments and their items after they're passed in. - * - * Return value: - **/ -EMPopupTargetAttachments * -em_popup_target_new_attachments(EMPopup *emp, GSList *attachments) -{ - EMPopupTargetAttachments *t = e_popup_target_new(&emp->popup, EM_POPUP_TARGET_ATTACHMENTS, sizeof(*t)); - guint32 mask = ~0; - int len = g_slist_length(attachments); - - t->attachments = attachments; - if (len > 0) - mask &= ~ EM_POPUP_ATTACHMENTS_MANY; - if (len == 1 && ((EAttachment *)attachments->data)->is_available_local) { - - if (camel_content_type_is(((CamelDataWrapper *) ((EAttachment *) attachments->data)->body)->mime_type, "image", "*")) - mask &= ~ EM_POPUP_ATTACHMENTS_IMAGE; - if (CAMEL_IS_MIME_MESSAGE(camel_medium_get_content_object((CamelMedium *) ((EAttachment *) attachments->data)->body))) - mask &= ~EM_POPUP_ATTACHMENTS_MESSAGE; - - mask &= ~ EM_POPUP_ATTACHMENTS_ONE; - } - if (len > 1) - mask &= ~ EM_POPUP_ATTACHMENTS_MULTIPLE; - t->target.mask = mask; - - return t; -} - /* ********************************************************************** */ static void @@ -405,11 +363,7 @@ emp_part_popup_saveas(EPopup *ep, EPopupItem *item, void *data) EPopupTarget *t = ep->target; CamelMimePart *part = NULL; - /* If it is of type EM_POPUP_TARGET_ATTACHMENTS, we can assume the length is one. */ - if (t->type == EM_POPUP_TARGET_ATTACHMENTS) - part = ((EAttachment *) ((EMPopupTargetAttachments *) t)->attachments->data)->body; - else - part = ((EMPopupTargetPart *) t)->part; + part = ((EMPopupTargetPart *) t)->part; em_utils_save_part(ep->target->widget, _("Save As..."), part); } @@ -423,10 +377,7 @@ emp_part_popup_set_background(EPopup *ep, EPopupItem *item, void *data) unsigned int i=1; CamelMimePart *part = NULL; - if (t->type == EM_POPUP_TARGET_ATTACHMENTS) - part = ((EAttachment *) ((EMPopupTargetAttachments *) t)->attachments->data)->body; - else - part = ((EMPopupTargetPart *) t)->part; + part = ((EMPopupTargetPart *) t)->part; if (!part) return; @@ -497,10 +448,7 @@ emp_part_popup_reply_sender(EPopup *ep, EPopupItem *item, void *data) CamelMimeMessage *message; CamelMimePart *part; - if (t->type == EM_POPUP_TARGET_ATTACHMENTS) - part = ((EAttachment *) ((EMPopupTargetAttachments *) t)->attachments->data)->body; - else - part = ((EMPopupTargetPart *) t)->part; + part = ((EMPopupTargetPart *) t)->part; message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part); em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_SENDER, NULL); @@ -513,10 +461,7 @@ emp_part_popup_reply_list (EPopup *ep, EPopupItem *item, void *data) CamelMimeMessage *message; CamelMimePart *part; - if (t->type == EM_POPUP_TARGET_ATTACHMENTS) - part = ((EAttachment *) ((EMPopupTargetAttachments *) t)->attachments->data)->body; - else - part = ((EMPopupTargetPart *) t)->part; + part = ((EMPopupTargetPart *) t)->part; message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part); em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_LIST, NULL); @@ -529,10 +474,7 @@ emp_part_popup_reply_all (EPopup *ep, EPopupItem *item, void *data) CamelMimeMessage *message; CamelMimePart *part; - if (t->type == EM_POPUP_TARGET_ATTACHMENTS) - part = ((EAttachment *) ((EMPopupTargetAttachments *) t)->attachments->data)->body; - else - part = ((EMPopupTargetPart *) t)->part; + part = ((EMPopupTargetPart *) t)->part; message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part); em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_ALL, NULL); @@ -545,10 +487,7 @@ emp_part_popup_forward (EPopup *ep, EPopupItem *item, void *data) CamelMimeMessage *message; CamelMimePart *part; - if (t->type == EM_POPUP_TARGET_ATTACHMENTS) - part = ((EAttachment *) ((EMPopupTargetAttachments *) t)->attachments->data)->body; - else - part = ((EMPopupTargetPart *) t)->part; + part = ((EMPopupTargetPart *) t)->part; /* TODO: have a emfv specific override so we can get the parent folder uri */ message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *) part); @@ -566,17 +505,6 @@ static EMPopupItem emp_standard_object_popups[] = { { E_POPUP_ITEM, "20.part.00", N_("_Forward"), emp_part_popup_forward, NULL, "mail-forward", EM_POPUP_PART_MESSAGE }, }; -static EMPopupItem emp_attachment_object_popups[] = { - { E_POPUP_ITEM, "00.attach.00", N_("_Save As..."), emp_part_popup_saveas, NULL, "document-save-as", 0 }, - { E_POPUP_ITEM, "00.attach.10", N_("Set as _Background"), emp_part_popup_set_background, NULL, NULL, EM_POPUP_ATTACHMENTS_IMAGE }, - { E_POPUP_BAR, "05.attach", NULL, NULL, NULL, NULL, EM_POPUP_ATTACHMENTS_MESSAGE }, - { E_POPUP_ITEM, "05.attach.00", N_("_Reply to sender"), emp_part_popup_reply_sender, NULL, "mail-reply-sender" , EM_POPUP_ATTACHMENTS_MESSAGE }, - { E_POPUP_ITEM, "05.attach.01", N_("Reply to _List"), emp_part_popup_reply_list, NULL, NULL, EM_POPUP_ATTACHMENTS_MESSAGE}, - { E_POPUP_ITEM, "05.attach.03", N_("Reply to _All"), emp_part_popup_reply_all, NULL, "mail-reply-all", EM_POPUP_ATTACHMENTS_MESSAGE}, - { E_POPUP_BAR, "05.attach.10", NULL, NULL, NULL, NULL, EM_POPUP_ATTACHMENTS_MESSAGE }, - { E_POPUP_ITEM, "05.attach.15", N_("_Forward"), emp_part_popup_forward, NULL, "mail-forward", EM_POPUP_ATTACHMENTS_MESSAGE }, -}; - static const EPopupItem emp_standard_part_apps_bar = { E_POPUP_BAR, "99.object" }; /* ********************************************************************** */ @@ -634,10 +562,7 @@ emp_apps_open_in(EPopup *ep, EPopupItem *item, void *data) EPopupTarget *target = ep->target; CamelMimePart *part; - if (target->type == EM_POPUP_TARGET_ATTACHMENTS) - part = ((EAttachment *) ((EMPopupTargetAttachments *) target)->attachments->data)->body; - else - part = ((EMPopupTargetPart *) target)->part; + part = ((EMPopupTargetPart *) target)->part; path = em_utils_temp_save_part(target->widget, part, TRUE); if (path) { @@ -705,10 +630,7 @@ emp_add_vcard (EPopup *ep, EPopupItem *item, void *data) CamelStreamMem *mem; - if (target->type == EM_POPUP_TARGET_ATTACHMENTS) - part = ((EAttachment *) ((EMPopupTargetAttachments *) target)->attachments->data)->body; - else - part = ((EMPopupTargetPart *) target)->part; + part = ((EMPopupTargetPart *) target)->part; if (!part) return; @@ -762,25 +684,6 @@ emp_standard_menu_factory(EPopup *emp, void *data) items = emp_standard_object_popups; len = LEN(emp_standard_object_popups); break; } - case EM_POPUP_TARGET_ATTACHMENTS: { - EMPopupTargetAttachments *t = (EMPopupTargetAttachments *)emp->target; - GSList *list = t->attachments; - EAttachment *attachment; - - if (g_slist_length(list) != 1 || !((EAttachment *)list->data)->is_available_local) { - items = NULL; - len = 0; - break; - } - - /* Only one attachment selected */ - attachment = list->data; - mime_type = camel_data_wrapper_get_mime_type((CamelDataWrapper *)attachment->body); - filename = camel_mime_part_get_filename(attachment->body); - - items = emp_attachment_object_popups; - len = LEN(emp_attachment_object_popups); - break; } default: items = NULL; len = 0; @@ -942,21 +845,11 @@ static const EPopupHookTargetMask emph_folder_masks[] = { { NULL } }; -static const EPopupHookTargetMask emph_attachments_masks[] = { - { "one", EM_POPUP_ATTACHMENTS_ONE }, - { "many", EM_POPUP_ATTACHMENTS_MANY }, - { "multiple", EM_POPUP_ATTACHMENTS_MULTIPLE }, - { "image", EM_POPUP_ATTACHMENTS_IMAGE }, - { "message", EM_POPUP_ATTACHMENTS_MESSAGE }, - { NULL } -}; - static const EPopupHookTargetMap emph_targets[] = { { "select", EM_POPUP_TARGET_SELECT, emph_select_masks }, { "uri", EM_POPUP_TARGET_URI, emph_uri_masks }, { "part", EM_POPUP_TARGET_PART, emph_part_masks }, { "folder", EM_POPUP_TARGET_FOLDER, emph_folder_masks }, - { "attachments", EM_POPUP_TARGET_ATTACHMENTS, emph_attachments_masks }, { NULL } }; diff --git a/mail/em-popup.h b/mail/em-popup.h index fbe41a310a..77f80e5599 100644 --- a/mail/em-popup.h +++ b/mail/em-popup.h @@ -43,7 +43,6 @@ typedef struct _EMPopupClass EMPopupClass; * @EM_POPUP_TARGET_URI: A URI. * @EM_POPUP_TARGET_PART: A CamelMimePart message part. * @EM_POPUP_TARGET_FOLDER: A folder URI. - * @EM_POPUP_TARGET_ATTACHMENTS: A list of attachments. * * Defines the value of the targetid for all EMPopup target types. **/ @@ -51,8 +50,7 @@ enum _em_popup_target_t { EM_POPUP_TARGET_SELECT, EM_POPUP_TARGET_URI, EM_POPUP_TARGET_PART, - EM_POPUP_TARGET_FOLDER, - EM_POPUP_TARGET_ATTACHMENTS, + EM_POPUP_TARGET_FOLDER }; /** @@ -158,26 +156,10 @@ enum _em_popup_target_folder_t { EM_POPUP_FOLDER_NONSTATIC = 1<<6, /* Except static folders like Outbox.*/ }; -/** - * enum _em_popup_target_attachments_t - EMPopupTargetAttachments qualifiers. - * - * @EM_POPUP_ATTACHMENTS_ONE: There is one and only one attachment selected. - * @EM_POPUP_ATTACHMENTS_MANY: There is one or more attachments selected. - * - **/ -enum _em_popup_target_attachments_t { - EM_POPUP_ATTACHMENTS_ONE = 1<<0, /* only 1 selected */ - EM_POPUP_ATTACHMENTS_MANY = 1<<1, /* one or more selected */ - EM_POPUP_ATTACHMENTS_MULTIPLE = 1<<2, /* More than 1 selected */ - EM_POPUP_ATTACHMENTS_IMAGE = 1<<3, /* Image selected */ - EM_POPUP_ATTACHMENTS_MESSAGE = 1<<4 /* Message selected */ -}; - typedef struct _EMPopupTargetSelect EMPopupTargetSelect; typedef struct _EMPopupTargetURI EMPopupTargetURI; typedef struct _EMPopupTargetPart EMPopupTargetPart; typedef struct _EMPopupTargetFolder EMPopupTargetFolder; -typedef struct _EMPopupTargetAttachments EMPopupTargetAttachments; /** * struct _EMPopupTargetURI - An inline URI. @@ -241,20 +223,6 @@ struct _EMPopupTargetFolder { char *uri; }; -/** - * struct _EMPopupTargetAttachments - A list of composer attachments. - * - * @target: Superclass. - * @attachments: A GSList list of EMsgComposer attachments. - * - * This target is used to represent a selected list of attachments in - * the message composer attachment area. - **/ -struct _EMPopupTargetAttachments { - EPopupTarget target; - GSList *attachments; -}; - typedef struct _EPopupItem EMPopupItem; /* The object */ @@ -276,7 +244,6 @@ EMPopupTargetURI *em_popup_target_new_uri(EMPopup *emp, const char *uri); EMPopupTargetSelect *em_popup_target_new_select(EMPopup *emp, struct _CamelFolder *folder, const char *folder_uri, GPtrArray *uids); EMPopupTargetPart *em_popup_target_new_part(EMPopup *emp, struct _CamelMimePart *part, const char *mime_type); EMPopupTargetFolder *em_popup_target_new_folder(EMPopup *emp, const char *uri, guint32 info_flags, guint32 popup_flags); -EMPopupTargetAttachments *em_popup_target_new_attachments(EMPopup *emp, GSList *attachments); /* ********************************************************************** */ diff --git a/mail/mail-component.c b/mail/mail-component.c index 3b67c43ad4..556715d662 100644 --- a/mail/mail-component.c +++ b/mail/mail-component.c @@ -92,6 +92,8 @@ #include "e-util/e-non-intrusive-error-dialog.h" +#include "e-attachment-handler-mail.h" + #define MAILER_ERROR_LEVEL_KEY "/apps/evolution/mail/display/error_level" #define MAILER_ERROR_TIME_OUT_KEY "/apps/evolution/mail/display/error_timeout" @@ -1259,6 +1261,9 @@ mail_component_class_init (MailComponentClass *class) epv->setLineStatus = impl_setLineStatus; mepv->test = impl_mail_test; + + /* Register attachment handler types. */ + e_attachment_handler_mail_get_type (); } static void -- cgit From de003c135ac993e323edcbd97f74aa28c43601f1 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 27 Apr 2009 20:27:02 -0400 Subject: Use consistent variable names for GtkUIManager --- mail/mail-signature-editor.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'mail') diff --git a/mail/mail-signature-editor.c b/mail/mail-signature-editor.c index 912182f5ac..daee1db92c 100644 --- a/mail/mail-signature-editor.c +++ b/mail/mail-signature-editor.c @@ -327,7 +327,7 @@ static void signature_editor_init (ESignatureEditor *editor) { GtkActionGroup *action_group; - GtkUIManager *manager; + GtkUIManager *ui_manager; GtkWidget *container; GtkWidget *widget; GtkWidget *vbox; @@ -336,9 +336,9 @@ signature_editor_init (ESignatureEditor *editor) editor->priv = E_SIGNATURE_EDITOR_GET_PRIVATE (editor); vbox = GTKHTML_EDITOR (editor)->vbox; - manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (editor)); + ui_manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (editor)); - gtk_ui_manager_add_ui_from_string (manager, ui, -1, &error); + gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); handle_error (&error); action_group = gtk_action_group_new ("signature"); @@ -347,10 +347,10 @@ signature_editor_init (ESignatureEditor *editor) gtk_action_group_add_actions ( action_group, entries, G_N_ELEMENTS (entries), editor); - gtk_ui_manager_insert_action_group (manager, action_group, 0); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); editor->priv->action_group = g_object_ref (action_group); - gtk_ui_manager_ensure_update (manager); + gtk_ui_manager_ensure_update (ui_manager); gtk_window_set_title (GTK_WINDOW (editor), _("Edit Signature")); -- cgit From af5958acaa62952d7ad0b729ad477dbe570eab6d Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 27 Apr 2009 22:33:05 -0400 Subject: Cosmetic cleanups for EMFormat headers --- mail/em-format-html-display.h | 107 +++++++++++++++++++++----------- mail/em-format-html-print.h | 44 ++++++++++---- mail/em-format-html.h | 138 +++++++++++++++++++++++++++--------------- mail/em-format-quote.h | 44 +++++++++++--- mail/em-format.h | 106 ++++++++++++++++++-------------- 5 files changed, 288 insertions(+), 151 deletions(-) (limited to 'mail') diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h index 4e2e7c1f83..10a379d7f6 100644 --- a/mail/em-format-html-display.h +++ b/mail/em-format-html-display.h @@ -22,20 +22,40 @@ Concrete class for formatting mails to displayed html */ -#ifndef _EM_FORMAT_HTML_DISPLAY_H -#define _EM_FORMAT_HTML_DISPLAY_H - -#include "mail/em-format-html.h" +#ifndef EM_FORMAT_HTML_DISPLAY_H +#define EM_FORMAT_HTML_DISPLAY_H + +#include + +/* Standard GObject macros */ +#define EM_TYPE_FORMAT_HTML_DISPLAY \ + (em_format_html_display_get_type ()) +#define EM_FORMAT_HTML_DISPLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplay)) +#define EM_FORMAT_HTML_DISPLAY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplayClass)) +#define EM_IS_FORMAT_HTML_DISPLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EM_TYPE_FORMAT_HTML_DISPLAY)) +#define EM_IS_FORMAT_HTML_DISPLAY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EM_TYPE_FORMAT_HTML_DISPLAY)) +#define EM_FORMAT_HTML_DISPLAY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplayClass)) + +G_BEGIN_DECLS typedef struct _EMFormatHTMLDisplay EMFormatHTMLDisplay; typedef struct _EMFormatHTMLDisplayClass EMFormatHTMLDisplayClass; - -struct _CamelMimePart; +typedef struct _EMFormatHTMLDisplayPrivate EMFormatHTMLDisplayPrivate; struct _EMFormatHTMLDisplay { EMFormatHTML formathtml; - struct _EMFormatHTMLDisplayPrivate *priv; + EMFormatHTMLDisplayPrivate *priv; struct _ESearchingTokenizer *search_tok; @@ -59,33 +79,46 @@ struct _EMFormatHTMLDisplayClass { void (*on_url)(EMFormatHTMLDisplay *efhd, const char *uri); }; -GType em_format_html_display_get_type(void); -EMFormatHTMLDisplay *em_format_html_display_new(void); - -void em_format_html_display_goto_anchor(EMFormatHTMLDisplay *efhd, const char *name); - -void em_format_html_display_set_animate(EMFormatHTMLDisplay *efhd, gboolean state); -void em_format_html_display_set_caret_mode(EMFormatHTMLDisplay *efhd, gboolean state); - -void em_format_html_display_set_search(EMFormatHTMLDisplay *efhd, int type, GSList *strings); -void em_format_html_display_search(EMFormatHTMLDisplay *efhd); -void em_format_html_display_search_with (EMFormatHTMLDisplay *efhd, char *word); -void em_format_html_display_search_close (EMFormatHTMLDisplay *efhd); - -GtkWidget *em_format_html_get_search_dialog (EMFormatHTMLDisplay *efhd); - -void em_format_html_display_cut (EMFormatHTMLDisplay *efhd); -void em_format_html_display_copy (EMFormatHTMLDisplay *efhd); -void em_format_html_display_paste (EMFormatHTMLDisplay *efhd); - -void em_format_html_display_zoom_in (EMFormatHTMLDisplay *efhd); -void em_format_html_display_zoom_out (EMFormatHTMLDisplay *efhd); -void em_format_html_display_zoom_reset (EMFormatHTMLDisplay *efhd); - -gboolean em_format_html_display_popup_menu (EMFormatHTMLDisplay *efhd); - -/* experimental */ -struct _EPopupExtension; -void em_format_html_display_set_popup(EMFormatHTMLDisplay *, struct _EPopupExtension *); - -#endif /* !_EM_FORMAT_HTML_DISPLAY_H */ +GType em_format_html_display_get_type (void); +EMFormatHTMLDisplay * + em_format_html_display_new (void); + +void em_format_html_display_goto_anchor + (EMFormatHTMLDisplay *efhd, + const char *name); + +void em_format_html_display_set_animate + (EMFormatHTMLDisplay *efhd, + gboolean state); +void em_format_html_display_set_caret_mode + (EMFormatHTMLDisplay *efhd, + gboolean state); + +void em_format_html_display_set_search + (EMFormatHTMLDisplay *efhd, + int type, + GSList *strings); +void em_format_html_display_search (EMFormatHTMLDisplay *efhd); +void em_format_html_display_search_with + (EMFormatHTMLDisplay *efhd, + char *word); +void em_format_html_display_search_close + (EMFormatHTMLDisplay *efhd); + +GtkWidget * em_format_html_get_search_dialog(EMFormatHTMLDisplay *efhd); + +void em_format_html_display_cut (EMFormatHTMLDisplay *efhd); +void em_format_html_display_copy (EMFormatHTMLDisplay *efhd); +void em_format_html_display_paste (EMFormatHTMLDisplay *efhd); + +void em_format_html_display_zoom_in (EMFormatHTMLDisplay *efhd); +void em_format_html_display_zoom_out (EMFormatHTMLDisplay *efhd); +void em_format_html_display_zoom_reset + (EMFormatHTMLDisplay *efhd); + +gboolean em_format_html_display_popup_menu + (EMFormatHTMLDisplay *efhd); + +G_END_DECLS + +#endif /* EM_FORMAT_HTML_DISPLAY_H */ diff --git a/mail/em-format-html-print.h b/mail/em-format-html-print.h index e308b065fa..ef25b63033 100644 --- a/mail/em-format-html-print.h +++ b/mail/em-format-html-print.h @@ -16,13 +16,32 @@ * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) */ -#ifndef _EM_FORMAT_HTML_PRINT_H -#define _EM_FORMAT_HTML_PRINT_H + +#ifndef EM_FORMAT_HTML_PRINT_H +#define EM_FORMAT_HTML_PRINT_H #include "mail/em-format-html.h" +/* Standard GObject macros */ #define EM_TYPE_FORMAT_HTML_PRINT \ (em_format_html_print_get_type ()) +#define EM_FORMAT_HTML_PRINT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EM_TYPE_FORMAT_HTML_PRINT, EMFormatHTMLPrint)) +#define EM_FORMAT_HTML_PRINT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EM_TYPE_FORMAT_HTML_PRINT, EMFormatHTMLPrintClass)) +#define EM_IS_FORMAT_HTML_PRINT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EM_TYPE_FORMAT_HTML_PRINT)) +#define EM_IS_FORMAT_HTML_PRINT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EM_TYPE_FORMAT_HTML_PRINT)) +#define EM_FORMAT_HTML_PRINT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EM_TYPE_FORMAT_HTML_PRINT, EMFormatHTMLPrintClass)) + +G_BEGIN_DECLS typedef struct _EMFormatHTMLPrint EMFormatHTMLPrint; typedef struct _EMFormatHTMLPrintClass EMFormatHTMLPrintClass; @@ -40,13 +59,16 @@ struct _EMFormatHTMLPrintClass { EMFormatHTMLClass parent_class; }; -GType em_format_html_print_get_type (void); -EMFormatHTMLPrint * em_format_html_print_new (EMFormatHTML *source, - GtkPrintOperationAction action); -void em_format_html_print_message (EMFormatHTMLPrint *efhp, - CamelFolder *folder, - const char *uid); -void em_format_html_print_raw_message (EMFormatHTMLPrint *efhp, - CamelMimeMessage *msg); +GType em_format_html_print_get_type (void); +EMFormatHTMLPrint * + em_format_html_print_new (EMFormatHTML *source, + GtkPrintOperationAction action); +void em_format_html_print_message (EMFormatHTMLPrint *efhp, + CamelFolder *folder, + const gchar *uid); +void em_format_html_print_raw_message(EMFormatHTMLPrint *efhp, + CamelMimeMessage *msg); + +G_END_DECLS -#endif /* ! _EM_FORMAT_HTML_PRINT_H */ +#endif /* EM_FORMAT_HTML_PRINT_H */ diff --git a/mail/em-format-html.h b/mail/em-format-html.h index a74432fdd9..a34f7b6915 100644 --- a/mail/em-format-html.h +++ b/mail/em-format-html.h @@ -25,24 +25,42 @@ Concrete class for formatting mails to html */ -#ifndef _EM_FORMAT_HTML_H -#define _EM_FORMAT_HTML_H - -#include "mail/em-format.h" +#ifndef EM_FORMAT_HTML_H +#define EM_FORMAT_HTML_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Standard GObject macros */ +#define EM_TYPE_FORMAT_HTML \ + (em_format_html_get_type ()) +#define EM_FORMAT_HTML(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EM_TYPE_FORMAT_HTML, EMFormatHTML)) +#define EM_FORMAT_HTML_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EM_TYPE_FORMAT_HTML, EMFormatHTMLClass)) +#define EM_IS_FORMAT_HTML(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EM_TYPE_FORMAT_HTML)) +#define EM_IS_FORMAT_HTML_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EM_TYPE_FORMAT_HTML)) +#define EM_FORMAT_HTML_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EM_TYPE_FORMAT_HTML, EMFormatHTMLClass)) + +G_BEGIN_DECLS typedef struct _EMFormatHTML EMFormatHTML; typedef struct _EMFormatHTMLClass EMFormatHTMLClass; - -#if 0 -struct _EMFormatHTMLHandler { - EFrormatHandler base; -}; -#endif - -struct _GtkHTMLEmbedded; -struct _CamelMimePart; -struct _CamelMedium; -struct _CamelStream; +typedef struct _EMFormatHTMLPrivate EMFormatHTMLPrivate; enum _em_format_html_header_flags { EM_FORMAT_HTML_HEADER_TO = 1<<0, @@ -55,9 +73,9 @@ typedef enum { EM_FORMAT_HTML_STATE_RENDERING } EMFormatHTMLState; -/* A HTMLJob will be executed in another thread, in sequence, +/* A HTMLJob will be executed in another thread, in sequence. It's job is to write to its stream, close it if successful, - then exit */ + then exit. */ typedef struct _EMFormatHTMLJob EMFormatHTMLJob; @@ -85,21 +103,21 @@ typedef struct _EMFormatHTMLJob EMFormatHTMLJob; * may be used to allocate these. **/ struct _EMFormatHTMLJob { - struct _EMFormatHTMLJob *next; - struct _EMFormatHTMLJob *prev; + EMFormatHTMLJob *next; + EMFormatHTMLJob *prev; EMFormatHTML *format; - struct _CamelStream *stream; + CamelStream *stream; /* We need to track the state of the visibility tree at the point this uri was generated */ struct _EMFormatPURITree *puri_level; - struct _CamelURL *base; + CamelURL *base; - void (*callback)(struct _EMFormatHTMLJob *job, int cancelled); + void (*callback)(EMFormatHTMLJob *job, int cancelled); union { char *uri; - struct _CamelMedium *msg; + CamelMedium *msg; EMFormatPURI *puri; struct _EMFormatPURITree *puri_level; void *data; @@ -109,7 +127,7 @@ struct _EMFormatHTMLJob { /* Pending object (classid: url) */ typedef struct _EMFormatHTMLPObject EMFormatHTMLPObject; -typedef gboolean (*EMFormatHTMLPObjectFunc)(EMFormatHTML *md, struct _GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject); +typedef gboolean (*EMFormatHTMLPObjectFunc)(EMFormatHTML *md, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject); /** * struct _EMFormatHTMLPObject - Pending object. @@ -130,16 +148,16 @@ typedef gboolean (*EMFormatHTMLPObjectFunc)(EMFormatHTML *md, struct _GtkHTMLEmb * em_format_html_add_pobject() may be used to allocate these. **/ struct _EMFormatHTMLPObject { - struct _EMFormatHTMLPObject *next; - struct _EMFormatHTMLPObject *prev; + EMFormatHTMLPObject *next; + EMFormatHTMLPObject *prev; - void (*free)(struct _EMFormatHTMLPObject *); - struct _EMFormatHTML *format; + void (*free)(EMFormatHTMLPObject *); + EMFormatHTML *format; char *classid; EMFormatHTMLPObjectFunc func; - struct _CamelMimePart *part; + CamelMimePart *part; }; #define EM_FORMAT_HTML_HEADER_NOCOLUMNS (EM_FORMAT_HEADER_LAST) @@ -180,9 +198,9 @@ struct _EMFormatHTMLPObject { struct _EMFormatHTML { EMFormat format; - struct _EMFormatHTMLPrivate *priv; + EMFormatHTMLPrivate *priv; - struct _GtkHTML *html; + GtkHTML *html; EDList pending_object_list; @@ -208,29 +226,49 @@ struct _EMFormatHTML { struct _EMFormatHTMLClass { EMFormatClass format_class; - }; -GType em_format_html_get_type(void); -EMFormatHTML *em_format_html_new(void); - -void em_format_html_load_http(EMFormatHTML *emf); +GType em_format_html_get_type (void); +EMFormatHTML * em_format_html_new (void); +void em_format_html_load_http (EMFormatHTML *efh); -void em_format_html_set_load_http(EMFormatHTML *emf, int style); -void em_format_html_set_mark_citations(EMFormatHTML *emf, int state, guint32 citation_colour); +void em_format_html_set_load_http (EMFormatHTML *efh, + int style); +void em_format_html_set_mark_citations + (EMFormatHTML *efh, + int state, + guint32 citation_colour); /* retrieves a pseudo-part icon wrapper for a file */ -struct _CamelMimePart *em_format_html_file_part(EMFormatHTML *efh, const char *mime_type, const char *filename); +CamelMimePart * em_format_html_file_part (EMFormatHTML *efh, + const gchar *mime_type, + const gchar *filename); /* for implementers */ -EMFormatHTMLPObject *em_format_html_add_pobject(EMFormatHTML *efh, size_t size, const char *classid, struct _CamelMimePart *part, EMFormatHTMLPObjectFunc func); -EMFormatHTMLPObject *em_format_html_find_pobject(EMFormatHTML *emf, const char *classid); -EMFormatHTMLPObject *em_format_html_find_pobject_func(EMFormatHTML *emf, struct _CamelMimePart *part, EMFormatHTMLPObjectFunc func); -void em_format_html_remove_pobject(EMFormatHTML *emf, EMFormatHTMLPObject *pobject); -void em_format_html_clear_pobject(EMFormatHTML *emf); - -EMFormatHTMLJob *em_format_html_job_new(EMFormatHTML *emfh, void (*callback)(struct _EMFormatHTMLJob *job, int cancelled), void *data) -; -void em_format_html_job_queue(EMFormatHTML *emfh, struct _EMFormatHTMLJob *job); - -#endif /* ! EM_FORMAT_HTML_H */ +EMFormatHTMLPObject * + em_format_html_add_pobject (EMFormatHTML *efh, + size_t size, + const char *classid, + CamelMimePart *part, + EMFormatHTMLPObjectFunc func); +EMFormatHTMLPObject * + em_format_html_find_pobject (EMFormatHTML *efh, + const char *classid); +EMFormatHTMLPObject * + em_format_html_find_pobject_func(EMFormatHTML *efh, + CamelMimePart *part, + EMFormatHTMLPObjectFunc func); +void em_format_html_remove_pobject (EMFormatHTML *efh, + EMFormatHTMLPObject *pobject); +void em_format_html_clear_pobject (EMFormatHTML *efh); + +EMFormatHTMLJob * + em_format_html_job_new (EMFormatHTML *efh, + void (*callback)(EMFormatHTMLJob *job, int cancelled), + void *data); +void em_format_html_job_queue (EMFormatHTML *efh, + EMFormatHTMLJob *job); + +G_END_DECLS + +#endif /* EM_FORMAT_HTML_H */ diff --git a/mail/em-format-quote.h b/mail/em-format-quote.h index 6b48fb87b4..87f0151a50 100644 --- a/mail/em-format-quote.h +++ b/mail/em-format-quote.h @@ -20,24 +20,47 @@ * */ -#ifndef _EM_FORMAT_QUOTE_H -#define _EM_FORMAT_QUOTE_H +#ifndef EM_FORMAT_QUOTE_H +#define EM_FORMAT_QUOTE_H +#include #include "mail/em-format.h" -typedef struct _EMFormatQuote EMFormatQuote; -typedef struct _EMFormatQuoteClass EMFormatQuoteClass; +/* Standard GObject macros */ +#define EM_TYPE_FORMAT_QUOTE \ + (em_format_quote_get_type ()) +#define EM_FORMAT_QUOTE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EM_TYPE_FORMAT_QUOTE, EMFormatQuote)) +#define EM_FORMAT_QUOTE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EM_TYPE_FORMAT_QUOTE, EMFormatQuoteClass)) +#define EM_IS_FORMAT_QUOTE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EM_TYPE_FORMAT_QUOTE)) +#define EM_IS_FORMAT_QUOTE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EM_TYPE_FORMAT_QUOTE)) +#define EM_FORMAT_QUOTE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EM_TYPE_FORMAT_QUOTE, EMFormatQuoteClass)) #define EM_FORMAT_QUOTE_CITE (1<<0) #define EM_FORMAT_QUOTE_HEADERS (1<<1) +G_BEGIN_DECLS + +typedef struct _EMFormatQuote EMFormatQuote; +typedef struct _EMFormatQuoteClass EMFormatQuoteClass; +typedef struct _EMFormatQuotePrivate EMFormatQuotePrivate; + struct _EMFormatQuote { EMFormat format; - struct _EMFormatQuotePrivate *priv; + EMFormatQuotePrivate *priv; char *credits; - struct _CamelStream *stream; + CamelStream *stream; guint32 flags; guint32 text_html_flags; @@ -48,8 +71,11 @@ struct _EMFormatQuoteClass { EMFormatClass format_class; }; -GType em_format_quote_get_type (void); +GType em_format_quote_get_type (void); +EMFormatQuote * em_format_quote_new (const gchar *credits, + CamelStream *stream, + guint32 flags); -EMFormatQuote *em_format_quote_new (const char *credits, struct _CamelStream *stream, guint32 flags); +G_END_DECLS -#endif /* !_EM_FORMAT_QUOTE_H */ +#endif /* EM_FORMAT_QUOTE_H */ diff --git a/mail/em-format.h b/mail/em-format.h index 1ca0cefb43..004d9c2e96 100644 --- a/mail/em-format.h +++ b/mail/em-format.h @@ -25,28 +25,48 @@ Abstract class for formatting mime messages */ -#ifndef _EM_FORMAT_H -#define _EM_FORMAT_H +#ifndef EM_FORMAT_H +#define EM_FORMAT_H #include -#include "libedataserver/e-msgport.h" - -struct _CamelStream; -struct _CamelMimePart; -struct _CamelMedium; -struct _CamelSession; -struct _CamelURL; -struct _CamelDataWrapper; -struct _CamelMimeMessage; -struct _CamelCipherValidity; +#include +#include +#include +#include +#include +#include +#include +#include + +/* Standard GObject macros */ +#define EM_TYPE_FORMAT \ + (em_format_get_type ()) +#define EM_FORMAT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EM_TYPE_FORMAT, EMFormat)) +#define EM_FORMAT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EM_TYPE_FORMAT, EMFormatClass)) +#define EM_IS_FORMAT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EM_TYPE_FORMAT)) +#define EM_IS_FORMAT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EM_TYPE_FORMAT)) +#define EM_FORMAT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EM_TYPE_FORMAT, EMFormatClass)) + +G_BEGIN_DECLS typedef struct _EMFormat EMFormat; typedef struct _EMFormatClass EMFormatClass; +typedef struct _EMFormatPrivate EMFormatPrivate; typedef struct _EMFormatHandler EMFormatHandler; typedef struct _EMFormatHeader EMFormatHeader; -typedef void (*EMFormatFunc) (EMFormat *md, struct _CamelStream *stream, struct _CamelMimePart *part, const EMFormatHandler *info); +typedef void (*EMFormatFunc) (EMFormat *md, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info); typedef enum _em_format_mode_t { EM_FORMAT_NORMAL, @@ -88,7 +108,7 @@ enum _em_format_handler_t { typedef struct _EMFormatPURI EMFormatPURI; -typedef void (*EMFormatPURIFunc)(EMFormat *md, struct _CamelStream *stream, EMFormatPURI *puri); +typedef void (*EMFormatPURIFunc)(EMFormat *md, CamelStream *stream, EMFormatPURI *puri); /** * struct _EMFormatPURI - Pending URI object. @@ -125,7 +145,7 @@ struct _EMFormatPURI { char *part_id; /* will always be set, emf->part_id->str for this part */ EMFormatPURIFunc func; - struct _CamelMimePart *part; + CamelMimePart *part; unsigned int use_count; /* used by multipart/related to see if it was accessed */ }; @@ -193,25 +213,25 @@ struct _EMFormatHeader { struct _EMFormat { GObject parent; - struct _EMFormatPrivate *priv; + EMFormatPrivate *priv; - struct _CamelMimeMessage *message; /* the current message */ + CamelMimeMessage *message; /* the current message */ - struct _CamelFolder *folder; + CamelFolder *folder; char *uid; GString *part_id; /* current part id prefix, for identifying parts directly */ EDList header_list; /* if empty, then all */ - struct _CamelSession *session; /* session, used for authentication when required */ - struct _CamelURL *base; /* content-base header or absolute content-location, for any part */ + CamelSession *session; /* session, used for authentication when required */ + CamelURL *base; /* content-base header or absolute content-location, for any part */ const char *snoop_mime_type; /* if we snooped an application/octet-stream type, what we snooped */ /* for validity enveloping */ - struct _CamelCipherValidity *valid; - struct _CamelCipherValidity *valid_parent; + CamelCipherValidity *valid; + CamelCipherValidity *valid_parent; /* for forcing inlining */ GHashTable *inline_table; @@ -242,28 +262,24 @@ struct _EMFormatClass { const EMFormatHandler *(*find_handler)(EMFormat *, const char *mime_type); /* start formatting a message */ - void (*format_clone)(EMFormat *, struct _CamelFolder *, const char *uid, struct _CamelMimeMessage *, EMFormat *); - - void *dummy0; + void (*format_clone)(EMFormat *, CamelFolder *, const char *uid, CamelMimeMessage *, EMFormat *); /* some internel error/inconsistency */ - void (*format_error)(EMFormat *, struct _CamelStream *, const char *msg); + void (*format_error)(EMFormat *, CamelStream *, const char *msg); /* use for external structured parts */ - void (*format_attachment)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *, const char *mime_type, const struct _EMFormatHandler *info); - - void *dummy1; + void (*format_attachment)(EMFormat *, CamelStream *, CamelMimePart *, const char *mime_type, const struct _EMFormatHandler *info); /* use for unparsable content */ - void (*format_source)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *); + void (*format_source)(EMFormat *, CamelStream *, CamelMimePart *); /* for outputing secure(d) content */ - void (*format_secure)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *, struct _CamelCipherValidity *); + void (*format_secure)(EMFormat *, CamelStream *, CamelMimePart *, CamelCipherValidity *); /* returns true if the formatter is still busy with pending stuff */ gboolean (*busy)(EMFormat *); /* Shows optional way to open messages */ - void (*format_optional)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *, struct _CamelStream* ); + void (*format_optional)(EMFormat *, CamelStream *, CamelMimePart *, CamelStream* ); /* signals */ /* complete, alternative to polling busy, for asynchronous work */ @@ -271,7 +287,7 @@ struct _EMFormatClass { }; /* helper entry point */ -void em_format_set_session(EMFormat *emf, struct _CamelSession *s); +void em_format_set_session(EMFormat *emf, CamelSession *s); void em_format_set_mode(EMFormat *emf, em_format_mode_t type); void em_format_set_charset(EMFormat *emf, const char *charset); @@ -284,12 +300,12 @@ void em_format_add_header(EMFormat *emf, const char *name, guint32 flags); /* FIXME: Need a 'clone' api to copy details about the current view (inlines etc) Or maybe it should live with sub-classes? */ -int em_format_is_attachment(EMFormat *emf, struct _CamelMimePart *part); +int em_format_is_attachment(EMFormat *emf, CamelMimePart *part); -int em_format_is_inline(EMFormat *emf, const char *partid, struct _CamelMimePart *part, const EMFormatHandler *handle); +int em_format_is_inline(EMFormat *emf, const char *partid, CamelMimePart *part, const EMFormatHandler *handle); void em_format_set_inline(EMFormat *emf, const char *partid, int state); -char *em_format_describe_part(struct _CamelMimePart *part, const char *mimetype); +char *em_format_describe_part(CamelMimePart *part, const char *mimetype); /* for implementers */ GType em_format_get_type(void); @@ -300,7 +316,7 @@ void em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info); const EMFormatHandler *em_format_fallback_handler(EMFormat *emf, const char *mime_type); /* puri is short for pending uri ... really */ -EMFormatPURI *em_format_add_puri(EMFormat *emf, size_t size, const char *uri, struct _CamelMimePart *part, EMFormatPURIFunc func); +EMFormatPURI *em_format_add_puri(EMFormat *emf, size_t size, const char *uri, CamelMimePart *part, EMFormatPURIFunc func); EMFormatPURI *em_format_find_visible_puri(EMFormat *emf, const char *uri); EMFormatPURI *em_format_find_puri(EMFormat *emf, const char *uri); void em_format_clear_puri_tree(EMFormat *emf); @@ -316,20 +332,22 @@ void em_format_pull_level(EMFormat *emf); ((EMFormat *)(emf))->uid, \ ((EMFormat *)(emf))->message, \ (EMFormat *)(emf)) -void em_format_format_error(EMFormat *emf, struct _CamelStream *stream, const char *fmt, ...); +void em_format_format_error(EMFormat *emf, CamelStream *stream, const char *fmt, ...); #define em_format_format_attachment(emf, stream, msg, type, info) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_attachment((emf), (stream), (msg), (type), (info)) #define em_format_format_source(emf, stream, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_source((emf), (stream), (msg)) -void em_format_format_secure(EMFormat *emf, struct _CamelStream *stream, struct _CamelMimePart *part, struct _CamelCipherValidity *valid); +void em_format_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid); #define em_format_busy(emf) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->busy((emf)) /* raw content only */ -void em_format_format_content(EMFormat *emf, struct _CamelStream *stream, struct _CamelMimePart *part); +void em_format_format_content(EMFormat *emf, CamelStream *stream, CamelMimePart *part); /* raw content text parts - should this just be checked/done by above? */ -void em_format_format_text(EMFormat *emf, struct _CamelStream *stream, struct _CamelDataWrapper *part); +void em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *part); -void em_format_part_as(EMFormat *emf, struct _CamelStream *stream, struct _CamelMimePart *part, const char *mime_type); -void em_format_part(EMFormat *emf, struct _CamelStream *stream, struct _CamelMimePart *part); +void em_format_part_as(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const char *mime_type); +void em_format_part(EMFormat *emf, CamelStream *stream, CamelMimePart *part); void em_format_merge_handler(EMFormat *new, EMFormat *old); -#endif /* ! _EM_FORMAT_H */ +G_END_DECLS + +#endif /* EM_FORMAT_H */ -- cgit From a08f6f0876fce40131c3915309591d775372f10c Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 28 Apr 2009 13:42:11 +0200 Subject: Do not mark newly recognized Junk messages Read ** Fix for bug #579550 --- mail/ChangeLog | 8 ++++++++ mail/mail-session.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index 586cb1b7bf..97599a4a20 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,11 @@ +2009-04-28 Milan Crha + + ** Fix for bug #579550 + + * mail-session.c: (main_get_filter_driver): + Do not mark messages recognized as junk Seen, to let user notice new + messages in a junk folder. + 2009-04-27 Milan Crha ** Fix for bug #579635 diff --git a/mail/mail-session.c b/mail/mail-session.c index 4997a29db0..e02ea41b55 100644 --- a/mail/mail-session.c +++ b/mail/mail-session.c @@ -544,7 +544,7 @@ main_get_filter_driver (CamelSession *session, const char *type, CamelException if ((!strcmp (type, FILTER_SOURCE_INCOMING) || !strcmp (type, FILTER_SOURCE_JUNKTEST)) && camel_session_check_junk (session)) { /* implicit junk check as 1st rule */ - camel_filter_driver_add_rule (driver, "Junk check", "(junk-test)", "(begin (set-system-flag \"junk\")(set-system-flag \"seen\"))"); + camel_filter_driver_add_rule (driver, "Junk check", "(junk-test)", "(begin (set-system-flag \"junk\"))"); } if (strcmp (type, FILTER_SOURCE_JUNKTEST) != 0) { -- cgit From c868ace2e93942aef027085353bff2bd736584b3 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 28 Apr 2009 16:31:45 +0200 Subject: Fix filter breakage after deprecated Gtk+ symbols removal ** Fix for bug #572348 * filter/filter-option.c: (combobox_changed), (get_widget): * mail/em-filter-rule.c: (part_combobox_changed): * mail/em-filter-source-element.c: (source_changed): Fix breakage of filter options. --- mail/ChangeLog | 8 ++++++++ mail/em-filter-rule.c | 2 +- mail/em-filter-source-element.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index 97599a4a20..359083a65e 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,11 @@ +2009-04-28 Milan Crha + + ** Fix for bug #572348 + + * em-filter-rule.c: (part_combobox_changed): + * em-filter-source-element.c: (source_changed): + Fix breakage of filter options. + 2009-04-28 Milan Crha ** Fix for bug #579550 diff --git a/mail/em-filter-rule.c b/mail/em-filter-rule.c index 10f06e38da..45dd78c708 100644 --- a/mail/em-filter-rule.c +++ b/mail/em-filter-rule.c @@ -331,7 +331,7 @@ part_combobox_changed (GtkComboBox *combobox, struct _part_data *data) int index, i; index = gtk_combo_box_get_active (combobox); - for (i = 0, part = rule_context_next_part (RULE_CONTEXT (data->f), part); part && i < index; i++, part = rule_context_next_part (RULE_CONTEXT (data->f), part)) { + for (i = 0, part = em_filter_context_next_action (data->f, part); part && i < index; i++, part = em_filter_context_next_action (data->f, part)) { /* traverse until reached index */ } diff --git a/mail/em-filter-source-element.c b/mail/em-filter-source-element.c index 096f91b2dd..e35871638f 100644 --- a/mail/em-filter-source-element.c +++ b/mail/em-filter-source-element.c @@ -240,7 +240,7 @@ source_changed(GtkComboBox *combobox, EMFilterSourceElement *fs) idx = gtk_combo_box_get_active (combobox); g_return_if_fail (idx >= 0 && idx < g_list_length (fs->priv->sources)); - info = (SourceInfo *) g_list_nth (fs->priv->sources, idx); + info = (SourceInfo *) g_list_nth_data (fs->priv->sources, idx); g_return_if_fail (info != NULL); g_free (fs->priv->current_url); -- cgit