diff options
Diffstat (limited to 'mail/em-composer-utils.c')
-rw-r--r-- | mail/em-composer-utils.c | 348 |
1 files changed, 232 insertions, 116 deletions
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c index 88225669c8..381e7fbfc5 100644 --- a/mail/em-composer-utils.c +++ b/mail/em-composer-utils.c @@ -37,20 +37,22 @@ #include "mail-config.h" #include "mail-session.h" #include "mail-send-recv.h" -#include "mail-component.h" #include "e-util/e-error.h" +#include "e-util/e-account-utils.h" #include "em-utils.h" #include "em-composer-utils.h" #include "composer/e-msg-composer.h" #include "composer/e-composer-autosave.h" +#include "composer/e-composer-post-header.h" +#include "em-folder-selector.h" +#include "em-folder-tree.h" #include "em-format-html.h" +#include "em-format-html-print.h" #include "em-format-quote.h" #include "em-event.h" -#include "libedataserver/e-account-list.h" - #include <camel/camel-folder.h> #include <camel/camel-multipart.h> #include <camel/camel-string-utils.h> @@ -58,6 +60,8 @@ #include <camel/camel-nntp-address.h> #include <camel/camel-vee-folder.h> +#include "e-mail-shell-module.h" + #ifdef G_OS_WIN32 /* Undef the similar macro from pthread.h, it doesn't check if * gmtime() returns NULL. @@ -72,6 +76,9 @@ static EAccount * guess_account (CamelMimeMessage *message, CamelFolder *folder); +static void em_utils_composer_send_cb (EMsgComposer *composer); +static void em_utils_composer_save_draft_cb (EMsgComposer *composer); + struct emcs_t { unsigned int ref_count; @@ -88,28 +95,67 @@ emcs_new (void) { struct emcs_t *emcs; - emcs = g_new (struct emcs_t, 1); + emcs = g_new0 (struct emcs_t, 1); emcs->ref_count = 1; - emcs->drafts_folder = NULL; - emcs->drafts_uid = NULL; - emcs->folder = NULL; - emcs->flags = 0; - emcs->set = 0; - emcs->uid = NULL; return emcs; } static void +emcs_set_drafts_info (struct emcs_t *emcs, + CamelFolder *drafts_folder, + const gchar *drafts_uid) +{ + g_return_if_fail (emcs != NULL); + g_return_if_fail (drafts_folder != NULL); + g_return_if_fail (drafts_uid != NULL); + + if (emcs->drafts_folder != NULL) + camel_object_unref (emcs->drafts_folder); + g_free (emcs->drafts_uid); + + camel_object_ref (drafts_folder); + emcs->drafts_folder = drafts_folder; + emcs->drafts_uid = g_strdup (drafts_uid); + + g_debug ("%s", G_STRFUNC); +} + +static void +emcs_set_folder_info (struct emcs_t *emcs, + CamelFolder *folder, + const gchar *uid, + guint32 flags, + guint32 set) +{ + g_return_if_fail (emcs != NULL); + g_return_if_fail (folder != NULL); + g_return_if_fail (uid != NULL); + + if (emcs->folder != NULL) + camel_object_unref (emcs->folder); + g_free (emcs->uid); + + camel_object_ref (folder); + emcs->folder = folder; + emcs->uid = g_strdup (uid); + emcs->flags = flags; + emcs->set = set; + + g_debug ("%s", G_STRFUNC); +} + +static void free_emcs (struct emcs_t *emcs) { - if (emcs->drafts_folder) + if (emcs->drafts_folder != NULL) camel_object_unref (emcs->drafts_folder); g_free (emcs->drafts_uid); - if (emcs->folder) + if (emcs->folder != NULL) camel_object_unref (emcs->folder); g_free (emcs->uid); + g_free (emcs); } @@ -127,12 +173,6 @@ emcs_unref (struct emcs_t *emcs) free_emcs (emcs); } -static void -composer_destroy_cb (gpointer user_data, GObject *deadbeef) -{ - emcs_unref (user_data); -} - static gboolean ask_confirm_for_unwanted_html_mail (EMsgComposer *composer, EDestination **recipients) { @@ -226,17 +266,6 @@ composer_send_queued_cb (CamelFolder *folder, CamelMimeMessage *msg, CamelMessag mail_send (); } } else { - if (!emcs) { - /* disconnect the previous signal handlers */ - g_signal_handlers_disconnect_matched (send->composer, G_SIGNAL_MATCH_FUNC, 0, - 0, NULL, em_utils_composer_send_cb, NULL); - g_signal_handlers_disconnect_matched (send->composer, G_SIGNAL_MATCH_FUNC, 0, - 0, NULL, em_utils_composer_save_draft_cb, NULL); - - /* reconnect to the signals using a non-NULL emcs for the callback data */ - em_composer_utils_setup_default_callbacks (send->composer); - } - e_msg_composer_set_enable_autosave (send->composer, TRUE); gtk_widget_show (GTK_WIDGET (send->composer)); } @@ -416,8 +445,8 @@ composer_get_message (EMsgComposer *composer, gboolean save_html_object_data) return message; } -void -em_utils_composer_send_cb (EMsgComposer *composer, gpointer user_data) +static void +em_utils_composer_send_cb (EMsgComposer *composer) { EComposerHeaderTable *table; CamelMimeMessage *message; @@ -429,32 +458,36 @@ em_utils_composer_send_cb (EMsgComposer *composer, gpointer user_data) table = e_msg_composer_get_header_table (composer); account = e_composer_header_table_get_account (table); if (!account || !account->enabled) { - e_error_run((GtkWindow *)composer, "mail:send-no-account-enabled", NULL); + e_error_run ( + GTK_WINDOW (composer), + "mail:send-no-account-enabled", NULL); return; } - if (!(message = composer_get_message (composer, FALSE))) + if ((message = composer_get_message (composer, FALSE)) == NULL) return; - mail_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX); + mail_folder = e_mail_shell_module_get_folder ( + mail_shell_module, E_MAIL_FOLDER_OUTBOX); camel_object_ref (mail_folder); /* mail the message */ - info = camel_message_info_new(NULL); - camel_message_info_set_flags(info, CAMEL_MESSAGE_SEEN, ~0); + info = camel_message_info_new (NULL); + camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0); send = g_malloc (sizeof (*send)); - send->emcs = user_data; + send->emcs = g_object_get_data (G_OBJECT (composer), "emcs"); if (send->emcs) emcs_ref (send->emcs); send->send = TRUE; - send->composer = composer; - g_object_ref (composer); + send->composer = g_object_ref (composer); gtk_widget_hide (GTK_WIDGET (composer)); e_msg_composer_set_enable_autosave (composer, FALSE); - mail_append_mail (mail_folder, message, info, composer_send_queued_cb, send); + mail_append_mail ( + mail_folder, message, info, composer_send_queued_cb, send); + camel_object_unref (mail_folder); camel_object_unref (message); } @@ -493,17 +526,9 @@ save_draft_done (CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *i composer_set_no_change (sdi->composer, FALSE); - if ((emcs = sdi->emcs) == NULL) { + if ((emcs = sdi->emcs) == NULL) emcs = emcs_new (); - /* disconnect the previous signal handlers */ - g_signal_handlers_disconnect_by_func (sdi->composer, G_CALLBACK (em_utils_composer_send_cb), NULL); - g_signal_handlers_disconnect_by_func (sdi->composer, G_CALLBACK (em_utils_composer_save_draft_cb), NULL); - - /* reconnect to the signals using a non-NULL emcs for the callback data */ - em_composer_utils_setup_default_callbacks (sdi->composer); - } - if (emcs->drafts_folder) { /* delete the original draft message */ camel_folder_set_message_flags (emcs->drafts_folder, emcs->drafts_uid, @@ -555,13 +580,13 @@ save_draft_folder (char *uri, CamelFolder *folder, gpointer data) } } -void -em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data) +static void +em_utils_composer_save_draft_cb (EMsgComposer *composer) { - const char *default_drafts_folder_uri = mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS); - CamelFolder *drafts_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS); + CamelFolder *local_drafts_folder; EComposerHeaderTable *table; struct _save_draft_info *sdi; + const gchar *local_drafts_folder_uri; CamelFolder *folder = NULL; CamelMimeMessage *msg; CamelMessageInfo *info; @@ -571,19 +596,25 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data) * get destroyed while we're in mail_msg_wait() a little lower * down, waiting for the folder to open */ - g_object_ref(composer); + local_drafts_folder = e_mail_shell_module_get_folder ( + mail_shell_module, E_MAIL_FOLDER_DRAFTS); + + local_drafts_folder_uri = e_mail_shell_module_get_folder_uri ( + mail_shell_module, E_MAIL_FOLDER_DRAFTS); + + g_object_ref (composer); msg = e_msg_composer_get_message_draft (composer); table = e_msg_composer_get_header_table (composer); account = e_composer_header_table_get_account (table); - sdi = g_malloc(sizeof(struct _save_draft_info)); + sdi = g_malloc (sizeof(struct _save_draft_info)); sdi->composer = composer; - sdi->emcs = user_data; + sdi->emcs = g_object_get_data (G_OBJECT (composer), "emcs"); if (sdi->emcs) - emcs_ref(sdi->emcs); + emcs_ref (sdi->emcs); if (account && account->drafts_folder_uri && - strcmp (account->drafts_folder_uri, default_drafts_folder_uri) != 0) { + strcmp (account->drafts_folder_uri, local_drafts_folder_uri) != 0) { int id; id = mail_get_folder (account->drafts_folder_uri, 0, save_draft_folder, &folder, mail_msg_unordered_push); @@ -599,11 +630,11 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data) return; } - folder = drafts_folder; - camel_object_ref (drafts_folder); + folder = local_drafts_folder; + camel_object_ref (local_drafts_folder); } } else { - folder = drafts_folder; + folder = local_drafts_folder; camel_object_ref (folder); } @@ -615,43 +646,24 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data) camel_object_unref (msg); } -void -em_composer_utils_setup_callbacks (EMsgComposer *composer, - CamelFolder *folder, - const char *uid, - guint32 flags, - guint32 set, - CamelFolder *drafts, - const char *drafts_uid) +static void +em_utils_composer_print_cb (EMsgComposer *composer, + GtkPrintOperationAction action) { - struct emcs_t *emcs; - - emcs = emcs_new (); - - if (folder && uid) { - camel_object_ref (folder); - emcs->folder = folder; - emcs->uid = g_strdup (uid); - emcs->flags = flags; - emcs->set = set; - } - - if (drafts && drafts_uid) { - camel_object_ref (drafts); - emcs->drafts_folder = drafts; - emcs->drafts_uid = g_strdup (drafts_uid); - } + CamelMimeMessage *message; + EMFormatHTMLPrint *efhp; - g_signal_connect (composer, "send", G_CALLBACK (em_utils_composer_send_cb), emcs); - g_signal_connect (composer, "save-draft", G_CALLBACK (em_utils_composer_save_draft_cb), emcs); + message = e_msg_composer_get_message_print (composer, 1); - g_object_weak_ref ((GObject *) composer, (GWeakNotify) composer_destroy_cb, emcs); + efhp = em_format_html_print_new (NULL, action); + em_format_html_print_raw_message (efhp, message); + g_object_unref (efhp); } /* Composing messages... */ static EMsgComposer * -create_new_composer (const char *subject, const char *fromuri, gboolean use_default_callbacks) +create_new_composer (const char *subject, const char *fromuri) { EMsgComposer *composer; EComposerHeaderTable *table; @@ -662,15 +674,12 @@ create_new_composer (const char *subject, const char *fromuri, gboolean use_defa return NULL; if (fromuri) - account = mail_config_get_account_by_source_url(fromuri); + account = mail_config_get_account_by_source_url (fromuri); table = e_msg_composer_get_header_table (composer); e_composer_header_table_set_account (table, account); e_composer_header_table_set_subject (table, subject); - if (use_default_callbacks) - em_composer_utils_setup_default_callbacks (composer); - return composer; } @@ -685,7 +694,7 @@ em_utils_compose_new_message (const char *fromuri) { GtkWidget *composer; - composer = (GtkWidget *) create_new_composer ("", fromuri, TRUE); + composer = (GtkWidget *) create_new_composer ("", fromuri); if (composer == NULL) return; @@ -715,7 +724,6 @@ em_utils_compose_new_message_with_mailto (const char *url, const char *fromuri) composer = e_msg_composer_new (); table = e_msg_composer_get_header_table (composer); - em_composer_utils_setup_default_callbacks (composer); if (fromuri && (account = mail_config_get_account_by_source_url(fromuri))) @@ -763,8 +771,6 @@ em_utils_post_to_folder (CamelFolder *folder) table, account->name); } - em_composer_utils_setup_default_callbacks (composer); - composer_set_no_change (composer, TRUE); gtk_widget_show ((GtkWidget *) composer); @@ -796,8 +802,6 @@ em_utils_post_to_url (const char *url) g_list_free (list); } - em_composer_utils_setup_default_callbacks (composer); - composer_set_no_change (composer, TRUE); gtk_widget_show ((GtkWidget *) composer); @@ -945,10 +949,12 @@ edit_message (CamelMimeMessage *message, CamelFolder *drafts, const char *uid) composer = e_msg_composer_new_with_message (message); - if (em_utils_folder_is_templates(drafts, NULL) == TRUE) - em_composer_utils_setup_callbacks (composer, NULL, NULL, 0, 0, NULL, NULL); - else - em_composer_utils_setup_callbacks (composer, NULL, NULL, 0, 0, drafts, uid); + if (em_utils_folder_is_drafts (drafts, NULL)) { + struct emcs_t *emcs; + + emcs = g_object_get_data (G_OBJECT (composer), "emcs"); + emcs_set_drafts_info (emcs, drafts, uid); + } composer_set_no_change (composer, TRUE); @@ -1071,7 +1077,7 @@ forward_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages, Cam { EMsgComposer *composer; - composer = create_new_composer (subject, fromuri, TRUE); + composer = create_new_composer (subject, fromuri); if (composer == NULL) return; @@ -1150,7 +1156,7 @@ forward_non_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages, text = em_utils_message_to_html (message, _("-------- Forwarded Message --------"), flags, &len, NULL, NULL); if (text) { - composer = create_new_composer (subject, fromuri, !uids || !uids->pdata [i]); + composer = create_new_composer (subject, fromuri); if (composer) { if (CAMEL_IS_MULTIPART(camel_medium_get_content_object((CamelMedium *)message))) @@ -1158,8 +1164,12 @@ forward_non_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages, e_msg_composer_set_body_text (composer, text, len); - if (uids && uids->pdata[i]) - em_composer_utils_setup_callbacks (composer, folder, uids->pdata[i], CAMEL_MESSAGE_FORWARDED, CAMEL_MESSAGE_FORWARDED, NULL, NULL); + if (uids && uids->pdata[i]) { + struct emcs_t *emcs; + + emcs = g_object_get_data (G_OBJECT (composer), "emcs"); + emcs_set_folder_info (emcs, folder, uids->pdata[i], CAMEL_MESSAGE_FORWARDED, CAMEL_MESSAGE_FORWARDED); + } composer_set_no_change (composer, TRUE); @@ -1315,8 +1325,6 @@ redirect_get_composer (CamelMimeMessage *message) composer = e_msg_composer_new_redirect (message, account ? account->name : NULL); - em_composer_utils_setup_default_callbacks (composer); - return composer; } @@ -1559,7 +1567,8 @@ em_utils_send_receipt (CamelFolder *folder, CamelMimeMessage *message) } /* Send the receipt */ - out_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX); + out_folder = e_mail_shell_module_get_folder ( + mail_shell_module, E_MAIL_FOLDER_OUTBOX); info = camel_message_info_new (NULL); camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); mail_append_mail (out_folder, receipt, info, em_utils_receipt_done, NULL); @@ -1655,7 +1664,7 @@ em_utils_forward_message_raw (CamelFolder *folder, CamelMimeMessage *message, co g_free (subject); /* and send it */ - out_folder = mail_component_get_folder (NULL, MAIL_COMPONENT_FOLDER_OUTBOX); + out_folder = e_mail_shell_module_get_folder (mail_shell_module, E_MAIL_FOLDER_OUTBOX); info = camel_message_info_new (NULL); camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); mail_append_mail (out_folder, forward, info, emu_forward_raw_done, NULL); @@ -1671,10 +1680,10 @@ generate_account_hash (void) EAccountList *accounts; EIterator *iter; - accounts = mail_config_get_accounts (); + accounts = e_get_account_list (); account_hash = g_hash_table_new (camel_strcase_hash, camel_strcase_equal); - def = mail_config_get_default_account (); + def = e_get_default_account (); iter = e_list_get_iterator ((EList *) accounts); while (e_iterator_is_valid (iter)) { @@ -2323,6 +2332,7 @@ em_utils_reply_to_message(CamelFolder *folder, const char *uid, CamelMimeMessage guint32 flags; EMEvent *eme; EMEventTargetMessage *target; + struct emcs_t *emcs; if (folder && uid && message == NULL) { struct _reply_data *rd = g_malloc0(sizeof(*rd)); @@ -2387,7 +2397,8 @@ em_utils_reply_to_message(CamelFolder *folder, const char *uid, CamelMimeMessage composer_set_body (composer, message, source); - em_composer_utils_setup_callbacks (composer, folder, uid, flags, flags, NULL, NULL); + emcs = g_object_get_data (G_OBJECT (composer), "emcs"); + emcs_set_folder_info (emcs, folder, uid, flags, flags); composer_set_no_change (composer, TRUE); @@ -2411,6 +2422,7 @@ post_reply_to_message (CamelFolder *folder, const char *uid, CamelMimeMessage *m char *real_uid; guint32 flags; GList *list = NULL; + struct emcs_t *emcs; if (message == NULL) return; @@ -2486,7 +2498,8 @@ post_reply_to_message (CamelFolder *folder, const char *uid, CamelMimeMessage *m composer_set_body (composer, message, NULL); - em_composer_utils_setup_callbacks (composer, real_folder, real_uid, flags, flags, NULL, NULL); + emcs = g_object_get_data (G_OBJECT (composer), "emcs"); + emcs_set_folder_info (emcs, real_folder, real_uid, flags, flags); composer_set_no_change (composer, TRUE); @@ -2514,3 +2527,106 @@ em_utils_post_reply_to_message_by_uid (CamelFolder *folder, const char *uid) mail_get_message (folder, uid, post_reply_to_message, NULL, mail_msg_unordered_push); } + +static void +post_header_clicked_cb (EComposerPostHeader *header, + EShellModule *shell_module) +{ + EMFolderTreeModel *model; + GtkWidget *folder_tree; + GtkWidget *dialog; + GList *list; + + model = e_mail_shell_module_get_folder_tree_model (shell_module); + folder_tree = em_folder_tree_new_with_model (model); + + em_folder_tree_set_multiselect ( + EM_FOLDER_TREE (folder_tree), TRUE); + em_folder_tree_set_excluded ( + EM_FOLDER_TREE (folder_tree), + EMFT_EXCLUDE_NOSELECT | + EMFT_EXCLUDE_VIRTUAL | + EMFT_EXCLUDE_VTRASH); + + dialog = em_folder_selector_new ( + EM_FOLDER_TREE (folder_tree), + EM_FOLDER_SELECTOR_CAN_CREATE, + _("Posting destination"), + _("Choose folders to post the message to."), + NULL); + + list = e_composer_post_header_get_folders (header); + em_folder_selector_set_selected_list ( + EM_FOLDER_SELECTOR (dialog), list); + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK) { + /* Prevent the header's "custom" flag from being reset, + * which is what the default method will do next. */ + g_signal_stop_emission_by_name (header, "clicked"); + goto exit; + } + + list = em_folder_selector_get_selected_uris ( + EM_FOLDER_SELECTOR (dialog)); + e_composer_post_header_set_folders (header, list); + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); + +exit: + gtk_widget_destroy (dialog); +} + +/** + * em_configure_new_composer: + * @composer: a newly created #EMsgComposer + * + * Integrates a newly created #EMsgComposer into the mail module. The + * composer can't link directly to the mail module without introducing + * circular library dependencies, so this function finishes configuring + * things the #EMsgComposer instance can't do itself. + **/ +void +em_configure_new_composer (EMsgComposer *composer) +{ + EComposerHeaderTable *table; + EComposerHeaderType header_type; + EComposerHeader *header; + struct emcs_t *emcs; + + g_return_if_fail (E_IS_MSG_COMPOSER (composer)); + + header_type = E_COMPOSER_HEADER_POST_TO; + table = e_msg_composer_get_header_table (composer); + header = e_composer_header_table_get_header (table, header_type); + + emcs = emcs_new (); + + g_object_set_data_full ( + G_OBJECT (composer), "emcs", emcs, + (GDestroyNotify) emcs_unref); + + g_signal_connect ( + composer, "send", + G_CALLBACK (em_utils_composer_send_cb), NULL); + + g_signal_connect ( + composer, "save-draft", + G_CALLBACK (em_utils_composer_save_draft_cb), NULL); + + g_signal_connect ( + composer, "print", + G_CALLBACK (em_utils_composer_print_cb), NULL); + + /* Handle "Post To:" button clicks, which displays a folder tree + * widget. The composer doesn't know about folder tree widgets, + * so it can't handle this itself. + * + * Note: This is a G_SIGNAL_RUN_LAST signal, which allows us to + * stop the signal emission if the user cancels or closes + * the folder selector dialog. See the handler function. */ + g_signal_connect ( + header, "clicked", + G_CALLBACK (post_header_clicked_cb), mail_shell_module); +} |