Bug 602612 - Add 'Alternative Reply' menu option
[evolution.git] / src / modules / mail / e-mail-attachment-handler.c
blob2ddec78f280ee3846521ff483163886b8bddb1f2
1 /*
2 * e-mail-attachment-handler.c
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
21 #include "evolution-config.h"
23 #include "e-mail-attachment-handler.h"
25 #include <glib/gi18n.h>
27 #include "mail/e-mail-backend.h"
28 #include "mail/e-mail-reader.h"
29 #include "mail/em-composer-utils.h"
30 #include "mail/em-utils.h"
32 #define E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE \
34 ((obj), E_TYPE_MAIL_ATTACHMENT_HANDLER, EMailAttachmentHandlerPrivate))
36 struct _EMailAttachmentHandlerPrivate {
37 EMailBackend *backend;
40 static gpointer parent_class;
41 static GType mail_attachment_handler_type;
43 static const gchar *ui =
44 "<ui>"
45 " <popup name='context'>"
46 " <placeholder name='custom-actions'>"
47 " <menuitem action='mail-message-edit'/>"
48 " <separator/>"
49 " <menuitem action='mail-reply-sender'/>"
50 " <menuitem action='mail-reply-list'/>"
51 " <menuitem action='mail-reply-all'/>"
52 " <menuitem action='mail-forward'/>"
53 " <menu action='mail-forward-as-menu'>"
54 " <menuitem action='mail-forward-attached'/>"
55 " <menuitem action='mail-forward-inline'/>"
56 " <menuitem action='mail-forward-quoted'/>"
57 " <separator/>"
58 " <menuitem action='mail-redirect'/>"
59 " </menu>"
60 " </placeholder>"
61 " </popup>"
62 "</ui>";
64 /* Note: Do not use the info field. */
65 static GtkTargetEntry target_table[] = {
66 { (gchar *) "message/rfc822", 0, 0 },
67 { (gchar *) "x-uid-list", 0, 0 }
70 static CamelFolder *
71 mail_attachment_handler_guess_folder_ref (EAttachmentHandler *handler)
73 EAttachmentView *view;
74 GtkWidget *widget;
76 view = e_attachment_handler_get_view (handler);
78 if (!view || !GTK_IS_WIDGET (view))
79 return NULL;
81 widget = GTK_WIDGET (view);
82 while (widget) {
83 if (E_IS_MAIL_READER (widget)) {
84 return e_mail_reader_ref_folder (E_MAIL_READER (widget));
87 widget = gtk_widget_get_parent (widget);
90 return NULL;
93 static CamelMimeMessage *
94 mail_attachment_handler_get_selected_message (EAttachmentHandler *handler)
96 EAttachment *attachment;
97 EAttachmentView *view;
98 CamelMimePart *mime_part;
99 CamelMimeMessage *message = NULL;
100 CamelDataWrapper *outer_wrapper;
101 CamelContentType *outer_content_type;
102 CamelDataWrapper *inner_wrapper;
103 CamelContentType *inner_content_type;
104 GList *selected;
105 gboolean inner_and_outer_content_types_match;
107 view = e_attachment_handler_get_view (handler);
109 selected = e_attachment_view_get_selected_attachments (view);
110 g_return_val_if_fail (g_list_length (selected) == 1, NULL);
112 attachment = E_ATTACHMENT (selected->data);
113 mime_part = e_attachment_ref_mime_part (attachment);
115 outer_wrapper =
116 camel_medium_get_content (CAMEL_MEDIUM (mime_part));
117 outer_content_type =
118 camel_data_wrapper_get_mime_type_field (outer_wrapper);
120 if (!camel_content_type_is (outer_content_type, "message", "rfc822"))
121 goto exit;
123 inner_wrapper =
124 camel_medium_get_content (CAMEL_MEDIUM (outer_wrapper));
125 inner_content_type =
126 camel_data_wrapper_get_mime_type_field (inner_wrapper);
128 inner_and_outer_content_types_match =
129 camel_content_type_is (
130 inner_content_type,
131 outer_content_type->type,
132 outer_content_type->subtype);
134 if (!inner_and_outer_content_types_match) {
135 CamelStream *mem;
136 gboolean success;
138 /* Create a message copy in case the inner content
139 * type doesn't match the mime_part's content type,
140 * which can happen for multipart/digest, where it
141 * confuses the formatter on reply, which skips all
142 * rfc822 subparts. */
143 mem = camel_stream_mem_new ();
144 camel_data_wrapper_write_to_stream_sync (
145 CAMEL_DATA_WRAPPER (outer_wrapper), mem, NULL, NULL);
147 g_seekable_seek (
148 G_SEEKABLE (mem), 0, G_SEEK_SET, NULL, NULL);
149 message = camel_mime_message_new ();
150 success = camel_data_wrapper_construct_from_stream_sync (
151 CAMEL_DATA_WRAPPER (message), mem, NULL, NULL);
152 if (!success)
153 g_clear_object (&message);
155 g_object_unref (mem);
158 exit:
159 if (message == NULL)
160 message = g_object_ref (outer_wrapper);
162 g_clear_object (&mime_part);
164 g_list_free_full (selected, (GDestroyNotify) g_object_unref);
166 return message;
169 typedef struct _CreateComposerData {
170 CamelMimeMessage *message;
171 CamelFolder *folder;
172 gboolean is_redirect;
174 gboolean is_reply;
175 EMailReplyType reply_type;
177 gboolean is_forward;
178 EMailForwardStyle forward_style;
179 } CreateComposerData;
181 static void
182 create_composer_data_free (CreateComposerData *ccd)
184 if (ccd) {
185 g_clear_object (&ccd->message);
186 g_clear_object (&ccd->folder);
187 g_free (ccd);
191 static void
192 mail_attachment_handler_composer_created_cb (GObject *source_object,
193 GAsyncResult *result,
194 gpointer user_data)
196 CreateComposerData *ccd = user_data;
197 EMsgComposer *composer;
198 GError *error = NULL;
200 g_return_if_fail (ccd != NULL);
202 composer = e_msg_composer_new_finish (result, &error);
203 if (error) {
204 g_warning ("%s: Failed to create msg composer: %s", G_STRFUNC, error->message);
205 g_clear_error (&error);
206 } else {
207 if (ccd->is_redirect) {
208 em_utils_redirect_message (composer, ccd->message);
209 } else if (ccd->is_reply) {
210 GSettings *settings;
211 EMailReplyStyle style;
213 settings = e_util_ref_settings ("org.gnome.evolution.mail");
214 style = g_settings_get_enum (settings, "reply-style-name");
215 g_object_unref (settings);
217 em_utils_reply_to_message (composer, ccd->message, NULL, NULL, ccd->reply_type, style, NULL, NULL, E_MAIL_REPLY_FLAG_NONE);
218 } else if (ccd->is_forward) {
219 em_utils_forward_message (composer, ccd->message, ccd->forward_style, ccd->folder, NULL);
220 } else {
221 em_utils_edit_message (composer, ccd->folder, ccd->message, NULL, TRUE);
225 create_composer_data_free (ccd);
228 static void
229 mail_attachment_handler_forward_with_style (EAttachmentHandler *handler,
230 EMailForwardStyle style)
232 EMailAttachmentHandlerPrivate *priv;
233 CamelMimeMessage *message;
234 CamelFolder *folder;
235 CreateComposerData *ccd;
236 EShell *shell;
238 priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
240 message = mail_attachment_handler_get_selected_message (handler);
241 g_return_if_fail (message != NULL);
243 folder = mail_attachment_handler_guess_folder_ref (handler);
244 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (priv->backend));
246 ccd = g_new0 (CreateComposerData, 1);
247 ccd->message = message;
248 ccd->folder = folder;
249 ccd->is_forward = TRUE;
250 ccd->forward_style = style;
252 e_msg_composer_new (shell, mail_attachment_handler_composer_created_cb, ccd);
255 static void
256 mail_attachment_handler_forward (GtkAction *action,
257 EAttachmentHandler *handler)
259 GSettings *settings;
260 EMailForwardStyle style;
262 settings = e_util_ref_settings ("org.gnome.evolution.mail");
263 style = g_settings_get_enum (settings, "forward-style-name");
264 g_object_unref (settings);
266 mail_attachment_handler_forward_with_style (handler, style);
269 static void
270 mail_attachment_handler_reply (EAttachmentHandler *handler,
271 EMailReplyType reply_type)
273 EMailAttachmentHandlerPrivate *priv;
274 CamelMimeMessage *message;
275 CreateComposerData *ccd;
276 EShellBackend *shell_backend;
277 EShell *shell;
279 priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
281 message = mail_attachment_handler_get_selected_message (handler);
282 g_return_if_fail (message != NULL);
284 shell_backend = E_SHELL_BACKEND (priv->backend);
285 shell = e_shell_backend_get_shell (shell_backend);
287 ccd = g_new0 (CreateComposerData, 1);
288 ccd->message = message;
289 ccd->reply_type = reply_type;
290 ccd->is_reply = TRUE;
292 e_msg_composer_new (shell, mail_attachment_handler_composer_created_cb, ccd);
295 static void
296 mail_attachment_handler_reply_all (GtkAction *action,
297 EAttachmentHandler *handler)
299 mail_attachment_handler_reply (handler, E_MAIL_REPLY_TO_ALL);
302 static void
303 mail_attachment_handler_reply_list (GtkAction *action,
304 EAttachmentHandler *handler)
306 mail_attachment_handler_reply (handler, E_MAIL_REPLY_TO_LIST);
309 static void
310 mail_attachment_handler_reply_sender (GtkAction *action,
311 EAttachmentHandler *handler)
313 mail_attachment_handler_reply (handler, E_MAIL_REPLY_TO_SENDER);
316 static void
317 mail_attachment_handler_message_edit (GtkAction *action,
318 EAttachmentHandler *handler)
320 EMailAttachmentHandlerPrivate *priv;
321 CamelMimeMessage *message;
322 CamelFolder *folder;
323 CreateComposerData *ccd;
324 EShell *shell;
326 priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
328 message = mail_attachment_handler_get_selected_message (handler);
329 g_return_if_fail (message != NULL);
331 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (priv->backend));
332 folder = mail_attachment_handler_guess_folder_ref (handler);
334 ccd = g_new0 (CreateComposerData, 1);
335 ccd->message = message;
336 ccd->folder = folder;
338 e_msg_composer_new (shell, mail_attachment_handler_composer_created_cb, ccd);
341 static void
342 mail_attachment_handler_forward_attached (GtkAction *action,
343 EAttachmentHandler *handler)
345 mail_attachment_handler_forward_with_style (handler, E_MAIL_FORWARD_STYLE_ATTACHED);
347 static void
348 mail_attachment_handler_forward_inline (GtkAction *action,
349 EAttachmentHandler *handler)
351 mail_attachment_handler_forward_with_style (handler, E_MAIL_FORWARD_STYLE_INLINE);
354 static void
355 mail_attachment_handler_forward_quoted (GtkAction *action,
356 EAttachmentHandler *handler)
358 mail_attachment_handler_forward_with_style (handler, E_MAIL_FORWARD_STYLE_QUOTED);
361 static void
362 mail_attachment_handler_redirect (GtkAction *action,
363 EAttachmentHandler *handler)
365 EMailAttachmentHandlerPrivate *priv;
366 CamelMimeMessage *message;
367 CreateComposerData *ccd;
368 EShell *shell;
370 priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
372 message = mail_attachment_handler_get_selected_message (handler);
373 g_return_if_fail (message != NULL);
375 shell = e_shell_backend_get_shell (E_SHELL_BACKEND (priv->backend));
377 ccd = g_new0 (CreateComposerData, 1);
378 ccd->message = message;
379 ccd->folder = NULL;
380 ccd->is_redirect = TRUE;
382 e_msg_composer_new (shell, mail_attachment_handler_composer_created_cb, ccd);
385 static GtkActionEntry standard_entries[] = {
387 { "mail-forward",
388 "mail-forward",
389 N_("_Forward"),
390 NULL,
391 N_("Forward the selected message to someone"),
392 G_CALLBACK (mail_attachment_handler_forward) },
394 { "mail-reply-all",
395 "mail-reply-all",
396 N_("Reply to _All"),
397 NULL,
398 N_("Compose a reply to all the recipients of the selected message"),
399 G_CALLBACK (mail_attachment_handler_reply_all) },
401 { "mail-reply-list",
402 NULL,
403 N_("Reply to _List"),
404 NULL,
405 N_("Compose a reply to the mailing list of the selected message"),
406 G_CALLBACK (mail_attachment_handler_reply_list) },
408 { "mail-reply-sender",
409 "mail-reply-sender",
410 N_("_Reply to Sender"),
411 NULL,
412 N_("Compose a reply to the sender of the selected message"),
413 G_CALLBACK (mail_attachment_handler_reply_sender) },
415 { "mail-message-edit",
416 NULL,
417 N_("_Edit as New Message..."),
418 NULL,
419 N_("Open the selected messages in the composer for editing"),
420 G_CALLBACK (mail_attachment_handler_message_edit) },
422 { "mail-forward-as-menu",
423 NULL,
424 N_("F_orward As"),
425 NULL,
426 NULL,
427 NULL },
429 { "mail-forward-attached",
430 NULL,
431 N_("_Attached"),
432 NULL,
433 N_("Forward the selected message to someone as an attachment"),
434 G_CALLBACK (mail_attachment_handler_forward_attached) },
436 { "mail-forward-inline",
437 NULL,
438 N_("_Inline"),
439 NULL,
440 N_("Forward the selected message in the body of a new message"),
441 G_CALLBACK (mail_attachment_handler_forward_inline) },
443 { "mail-forward-quoted",
444 NULL,
445 N_("_Quoted"),
446 NULL,
447 N_("Forward the selected message quoted like a reply"),
448 G_CALLBACK (mail_attachment_handler_forward_quoted) },
450 { "mail-redirect",
451 NULL,
452 N_("Re_direct"),
453 NULL,
454 N_("Redirect (bounce) the selected message to someone"),
455 G_CALLBACK (mail_attachment_handler_redirect) }
458 static void
459 call_attachment_load_handle_error (GObject *source_object,
460 GAsyncResult *result,
461 gpointer user_data)
463 GtkWindow *window = user_data;
465 g_return_if_fail (E_IS_ATTACHMENT (source_object));
466 g_return_if_fail (!window || GTK_IS_WINDOW (window));
468 e_attachment_load_handle_error (E_ATTACHMENT (source_object), result, window);
470 g_clear_object (&window);
473 static void
474 mail_attachment_handler_message_rfc822 (EAttachmentView *view,
475 GdkDragContext *drag_context,
476 gint x,
477 gint y,
478 GtkSelectionData *selection_data,
479 guint info,
480 guint time,
481 EAttachmentHandler *handler)
483 static GdkAtom atom = GDK_NONE;
484 EAttachmentStore *store;
485 EAttachment *attachment;
486 CamelMimeMessage *message;
487 CamelDataWrapper *wrapper;
488 CamelStream *stream;
489 const gchar *data;
490 gboolean success = FALSE;
491 gpointer parent;
492 gint length;
494 if (G_UNLIKELY (atom == GDK_NONE))
495 atom = gdk_atom_intern_static_string ("message/rfc822");
497 if (gtk_selection_data_get_target (selection_data) != atom)
498 return;
500 g_signal_stop_emission_by_name (view, "drag-data-received");
502 data = (const gchar *) gtk_selection_data_get_data (selection_data);
503 length = gtk_selection_data_get_length (selection_data);
505 stream = camel_stream_mem_new ();
506 camel_stream_write (stream, data, length, NULL, NULL);
507 g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL);
509 message = camel_mime_message_new ();
510 wrapper = CAMEL_DATA_WRAPPER (message);
512 if (!camel_data_wrapper_construct_from_stream_sync (
513 wrapper, stream, NULL, NULL))
514 goto exit;
516 store = e_attachment_view_get_store (view);
518 parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
519 parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
521 attachment = e_attachment_new_for_message (message);
522 e_attachment_store_add_attachment (store, attachment);
523 e_attachment_load_async (
524 attachment, (GAsyncReadyCallback)
525 call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
526 g_object_unref (attachment);
528 success = TRUE;
530 exit:
531 g_object_unref (message);
532 g_object_unref (stream);
534 gtk_drag_finish (drag_context, success, FALSE, time);
537 static gboolean
538 gather_x_uid_list_messages_cb (CamelFolder *folder,
539 const GPtrArray *uids,
540 gpointer user_data,
541 GCancellable *cancellable,
542 GError **error)
544 GSList **pmessages = user_data;
545 guint ii;
547 g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
548 g_return_val_if_fail (uids != NULL, FALSE);
549 g_return_val_if_fail (pmessages != NULL, FALSE);
551 for (ii = 0; ii < uids->len; ii++) {
552 CamelMimeMessage *message;
554 message = camel_folder_get_message_sync (folder, uids->pdata[ii], cancellable, error);
555 if (!message)
556 return FALSE;
558 *pmessages = g_slist_prepend (*pmessages, message);
561 return TRUE;
564 static void
565 mail_attachment_handler_x_uid_list (EAttachmentView *view,
566 GdkDragContext *drag_context,
567 gint x,
568 gint y,
569 GtkSelectionData *selection_data,
570 guint info,
571 guint time,
572 EAttachmentHandler *handler)
574 static GdkAtom atom = GDK_NONE;
575 EMailAttachmentHandlerPrivate *priv;
576 CamelDataWrapper *wrapper;
577 CamelMultipart *multipart;
578 CamelMimePart *mime_part;
579 EAttachment *attachment;
580 EAttachmentStore *store;
581 EMailSession *session;
582 GSList *messages = NULL, *link;
583 gchar *description;
584 gpointer parent;
585 GError *local_error = NULL;
587 if (G_UNLIKELY (atom == GDK_NONE))
588 atom = gdk_atom_intern_static_string ("x-uid-list");
590 if (gtk_selection_data_get_target (selection_data) != atom)
591 return;
593 store = e_attachment_view_get_store (view);
594 priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
596 parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
597 parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
599 session = e_mail_backend_get_session (priv->backend);
601 em_utils_selection_uidlist_foreach_sync (selection_data, session,
602 gather_x_uid_list_messages_cb, &messages, NULL, &local_error);
604 if (local_error || !messages)
605 goto exit;
607 /* Handle one message. */
608 if (!messages->next) {
609 attachment = e_attachment_new_for_message (messages->data);
610 e_attachment_store_add_attachment (store, attachment);
611 e_attachment_load_async (
612 attachment, (GAsyncReadyCallback)
613 call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
615 g_object_unref (attachment);
616 } else {
617 gint n_messages = g_slist_length (messages);
619 messages = g_slist_reverse (messages);
621 /* Build a multipart/digest message out of the UIDs. */
622 multipart = camel_multipart_new ();
623 wrapper = CAMEL_DATA_WRAPPER (multipart);
624 camel_data_wrapper_set_mime_type (wrapper, "multipart/digest");
625 camel_multipart_set_boundary (multipart, NULL);
627 for (link = messages; link; link = g_slist_next (link)) {
628 mime_part = camel_mime_part_new ();
629 wrapper = CAMEL_DATA_WRAPPER (link->data);
630 camel_mime_part_set_disposition (mime_part, "inline");
631 camel_medium_set_content (
632 CAMEL_MEDIUM (mime_part), wrapper);
633 camel_mime_part_set_content_type (mime_part, "message/rfc822");
634 camel_multipart_add_part (multipart, mime_part);
635 g_object_unref (mime_part);
638 mime_part = camel_mime_part_new ();
639 wrapper = CAMEL_DATA_WRAPPER (multipart);
640 camel_medium_set_content (CAMEL_MEDIUM (mime_part), wrapper);
642 description = g_strdup_printf (
643 ngettext (
644 "%d attached message",
645 "%d attached messages",
646 n_messages),
647 n_messages);
648 camel_mime_part_set_description (mime_part, description);
649 g_free (description);
651 attachment = e_attachment_new ();
652 e_attachment_set_mime_part (attachment, mime_part);
653 e_attachment_store_add_attachment (store, attachment);
654 e_attachment_load_async (
655 attachment, (GAsyncReadyCallback)
656 call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
657 g_object_unref (attachment);
659 g_object_unref (mime_part);
660 g_object_unref (multipart);
663 exit:
664 if (local_error != NULL) {
665 const gchar *folder_name = (const gchar *) gtk_selection_data_get_data (selection_data);
667 e_alert_run_dialog_for_args (
668 parent, "mail-composer:attach-nomessages",
669 folder_name, local_error->message, NULL);
671 g_clear_error (&local_error);
674 g_slist_free_full (messages, g_object_unref);
676 g_signal_stop_emission_by_name (view, "drag-data-received");
679 static void
680 mail_attachment_handler_update_actions (EAttachmentView *view,
681 EAttachmentHandler *handler)
683 EAttachment *attachment;
684 CamelMimePart *mime_part;
685 GtkActionGroup *action_group;
686 GtkAction *action;
687 GList *selected;
688 gboolean visible = FALSE, has_list_post = FALSE;
690 selected = e_attachment_view_get_selected_attachments (view);
692 if (g_list_length (selected) != 1)
693 goto exit;
695 attachment = E_ATTACHMENT (selected->data);
697 if (e_attachment_get_loading (attachment) ||
698 e_attachment_get_saving (attachment))
699 goto exit;
701 mime_part = e_attachment_ref_mime_part (attachment);
703 if (mime_part != NULL) {
704 CamelMedium *medium;
705 CamelDataWrapper *content;
707 medium = CAMEL_MEDIUM (mime_part);
708 content = camel_medium_get_content (medium);
709 visible = CAMEL_IS_MIME_MESSAGE (content);
711 if (visible)
712 has_list_post = camel_medium_get_header (CAMEL_MEDIUM (content), "List-Post") != NULL;
714 g_object_unref (mime_part);
717 exit:
718 action_group = e_attachment_view_get_action_group (view, "mail");
719 gtk_action_group_set_visible (action_group, visible);
721 action = gtk_action_group_get_action (action_group, "mail-reply-list");
722 gtk_action_set_visible (action, has_list_post);
724 g_list_foreach (selected, (GFunc) g_object_unref, NULL);
725 g_list_free (selected);
728 static void
729 mail_attachment_handler_dispose (GObject *object)
731 EMailAttachmentHandlerPrivate *priv;
733 priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (object);
735 g_clear_object (&priv->backend);
737 /* Chain up to parent's dispose() method. */
738 G_OBJECT_CLASS (parent_class)->dispose (object);
741 static void
742 mail_attachment_handler_constructed (GObject *object)
744 EMailAttachmentHandlerPrivate *priv;
745 EShell *shell;
746 EShellBackend *shell_backend;
747 EAttachmentHandler *handler;
748 EAttachmentView *view;
749 GtkActionGroup *action_group;
750 GtkUIManager *ui_manager;
751 GError *error = NULL;
753 handler = E_ATTACHMENT_HANDLER (object);
754 priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (object);
756 /* Chain up to parent's constructed() method. */
757 G_OBJECT_CLASS (parent_class)->constructed (object);
759 shell = e_shell_get_default ();
760 shell_backend = e_shell_get_backend_by_name (shell, "mail");
761 priv->backend = g_object_ref (shell_backend);
763 view = e_attachment_handler_get_view (handler);
765 action_group = e_attachment_view_add_action_group (view, "mail");
766 gtk_action_group_add_actions (
767 action_group, standard_entries,
768 G_N_ELEMENTS (standard_entries), handler);
770 ui_manager = e_attachment_view_get_ui_manager (view);
771 gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
773 if (error != NULL) {
774 g_warning ("%s", error->message);
775 g_error_free (error);
778 g_signal_connect (
779 view, "update-actions",
780 G_CALLBACK (mail_attachment_handler_update_actions),
781 handler);
783 g_signal_connect (
784 view, "drag-data-received",
785 G_CALLBACK (mail_attachment_handler_message_rfc822),
786 handler);
788 g_signal_connect (
789 view, "drag-data-received",
790 G_CALLBACK (mail_attachment_handler_x_uid_list),
791 handler);
794 static GdkDragAction
795 mail_attachment_handler_get_drag_actions (EAttachmentHandler *handler)
797 return GDK_ACTION_COPY;
800 static const GtkTargetEntry *
801 mail_attachment_handler_get_target_table (EAttachmentHandler *handler,
802 guint *n_targets)
804 if (n_targets != NULL)
805 *n_targets = G_N_ELEMENTS (target_table);
807 return target_table;
810 static void
811 mail_attachment_handler_class_init (EMailAttachmentHandlerClass *class)
813 GObjectClass *object_class;
814 EAttachmentHandlerClass *handler_class;
816 parent_class = g_type_class_peek_parent (class);
817 g_type_class_add_private (class, sizeof (EMailAttachmentHandlerPrivate));
819 object_class = G_OBJECT_CLASS (class);
820 object_class->dispose = mail_attachment_handler_dispose;
821 object_class->constructed = mail_attachment_handler_constructed;
823 handler_class = E_ATTACHMENT_HANDLER_CLASS (class);
824 handler_class->get_drag_actions = mail_attachment_handler_get_drag_actions;
825 handler_class->get_target_table = mail_attachment_handler_get_target_table;
828 static void
829 mail_attachment_handler_init (EMailAttachmentHandler *handler)
831 handler->priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
834 GType
835 e_mail_attachment_handler_get_type (void)
837 return mail_attachment_handler_type;
840 void
841 e_mail_attachment_handler_register_type (GTypeModule *type_module)
843 static const GTypeInfo type_info = {
844 sizeof (EMailAttachmentHandlerClass),
845 (GBaseInitFunc) NULL,
846 (GBaseFinalizeFunc) NULL,
847 (GClassInitFunc) mail_attachment_handler_class_init,
848 (GClassFinalizeFunc) NULL,
849 NULL, /* class_data */
850 sizeof (EMailAttachmentHandler),
851 0, /* n_preallocs */
852 (GInstanceInitFunc) mail_attachment_handler_init,
853 NULL /* value_table */
856 mail_attachment_handler_type = g_type_module_register_type (
857 type_module, E_TYPE_ATTACHMENT_HANDLER,
858 "EMailAttachmentHandler", &type_info, 0);