void mail_send (void) { CamelFolder *outbox_folder; EAccountService *transport; struct _send_info *info; struct _send_data *data; send_info_t type; transport = mail_config_get_default_transport (); if (!transport || !transport->url) return; data = setup_send_data (); info = g_hash_table_lookup (data->active, SEND_URI_KEY); if (info != NULL) { info->again++; d(printf("send of %s still in progress\n", transport->url)); return; } d(printf("starting non-interactive send of '%s'\n", transport->url)); type = get_receive_type (transport->url); if (type == SEND_INVALID) { d(printf ("unsupported provider: '%s'\n", transport->url)); return; } info = g_malloc0 (sizeof (*info)); info->type = SEND_SEND; info->progress_bar = NULL; info->status_label = NULL; info->uri = g_strdup (transport->url); info->keep = FALSE; info->cancel = NULL; info->cancel_button = NULL; info->data = data; info->state = SEND_ACTIVE; info->timeout_id = 0; d(printf("Adding new info %p\n", info)); g_hash_table_insert (data->active, SEND_URI_KEY, info); /* todo, store the folder in info? */ outbox_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX); mail_send_queue (outbox_folder, info->uri, FILTER_SOURCE_OUTGOING, info->cancel, receive_get_folder, info, receive_status, info, receive_done, info); }
static struct _send_data * build_dialog (EAccountList *accounts, CamelFolder *outbox, const char *destination) { GtkDialog *gd; GtkWidget *table; int row, num_sources; GList *list = NULL; struct _send_data *data; GtkWidget *send_icon; GtkWidget *recv_icon; GtkWidget *scrolled_window; GtkWidget *label; GtkWidget *status_label; GtkWidget *progress_bar; GtkWidget *cancel_button; struct _send_info *info; char *pretty_url; EAccount *account; EIterator *iter; GList *icon_list; EMEventTargetSendReceive *target; gd = (GtkDialog *)(send_recv_dialog = gtk_dialog_new_with_buttons(_("Send & Receive Mail"), NULL, GTK_DIALOG_NO_SEPARATOR, NULL)); gtk_window_set_modal ((GtkWindow *) gd, FALSE); gconf_bridge_bind_window_size ( gconf_bridge_get (), GCONF_KEY_PREFIX, GTK_WINDOW (send_recv_dialog)); gtk_widget_ensure_style ((GtkWidget *)gd); gtk_container_set_border_width ((GtkContainer *)gd->vbox, 0); gtk_container_set_border_width ((GtkContainer *)gd->action_area, 6); cancel_button = gtk_button_new_with_mnemonic (_("Cancel _All")); gtk_button_set_image ( GTK_BUTTON (cancel_button), gtk_image_new_from_stock ( GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON)); gtk_widget_show (cancel_button); gtk_dialog_add_action_widget (gd, cancel_button, GTK_RESPONSE_CANCEL); icon_list = e_icon_factory_get_icon_list ("mail-send-receive"); if (icon_list) { gtk_window_set_icon_list (GTK_WINDOW (gd), icon_list); g_list_foreach (icon_list, (GFunc) g_object_unref, NULL); g_list_free (icon_list); } num_sources = 0; iter = e_list_get_iterator ((EList *) accounts); while (e_iterator_is_valid (iter)) { account = (EAccount *) e_iterator_get (iter); if (account->source->url) num_sources++; e_iterator_next (iter); } g_object_unref (iter); table = gtk_table_new (num_sources, 4, FALSE); gtk_container_set_border_width (GTK_CONTAINER (table), 6); gtk_table_set_row_spacings (GTK_TABLE (table), 6); gtk_table_set_col_spacings (GTK_TABLE (table), 6); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_container_set_border_width ( GTK_CONTAINER (scrolled_window), 6); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW (scrolled_window), table); gtk_box_pack_start ( GTK_BOX (gd->vbox), scrolled_window, TRUE, TRUE, 0); gtk_widget_show (scrolled_window); /* must bet setup after send_recv_dialog as it may re-trigger send-recv button */ data = setup_send_data (); row = 0; iter = e_list_get_iterator ((EList *) accounts); while (e_iterator_is_valid (iter)) { EAccountService *source; account = (EAccount *) e_iterator_get (iter); source = account->source; if (!account->enabled || !source->url) { e_iterator_next (iter); continue; } /* see if we have an outstanding download active */ info = g_hash_table_lookup (data->active, source->url); if (info == NULL) { send_info_t type; type = get_receive_type (source->url); if (type == SEND_INVALID || type == SEND_SEND) { e_iterator_next (iter); continue; } info = g_malloc0 (sizeof (*info)); info->type = type; d(printf("adding source %s\n", source->url)); info->uri = g_strdup (source->url); info->keep = source->keep_on_server; info->cancel = camel_operation_new (operation_status, info); info->state = SEND_ACTIVE; info->timeout_id = g_timeout_add (STATUS_TIMEOUT, operation_status_timeout, info); g_hash_table_insert (data->active, info->uri, info); list = g_list_prepend (list, info); } else if (info->progress_bar != NULL) { /* incase we get the same source pop up again */ e_iterator_next (iter); continue; } else if (info->timeout_id == 0) info->timeout_id = g_timeout_add (STATUS_TIMEOUT, operation_status_timeout, info); recv_icon = e_icon_factory_get_image ( "mail-inbox", E_ICON_SIZE_LARGE_TOOLBAR); pretty_url = format_url (source->url, account->name); label = gtk_label_new (NULL); gtk_label_set_ellipsize ( GTK_LABEL (label), PANGO_ELLIPSIZE_END); gtk_label_set_markup (GTK_LABEL (label), pretty_url); g_free (pretty_url); progress_bar = gtk_progress_bar_new (); cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL); status_label = gtk_label_new ( (info->type == SEND_UPDATE) ? _("Updating...") : _("Waiting...")); gtk_label_set_ellipsize ( GTK_LABEL (status_label), PANGO_ELLIPSIZE_END); /* g_object_set(data->label, "bold", TRUE, NULL); */ gtk_misc_set_alignment (GTK_MISC (label), 0, .5); gtk_misc_set_alignment (GTK_MISC (status_label), 0, .5); gtk_table_attach ( GTK_TABLE (table), recv_icon, 0, 1, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), label, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), progress_bar, 2, 3, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), cancel_button, 3, 4, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), status_label, 1, 2, row+1, row+2, GTK_EXPAND | GTK_FILL, 0, 0, 0); info->progress_bar = progress_bar; info->status_label = status_label; info->cancel_button = cancel_button; info->data = data; g_signal_connect ( cancel_button, "clicked", G_CALLBACK (receive_cancel), info); e_iterator_next (iter); row = row + 2; } g_object_unref (iter); /* Hook: If some one wants to hook on to the sendreceive dialog, this is the way to go. */ target = em_event_target_new_send_receive (em_event_peek(), table, data, row, EM_EVENT_SEND_RECEIVE); e_event_emit ((EEvent *)em_event_peek (), "mail.sendreceive", (EEventTarget *) target); if (outbox && destination) { info = g_hash_table_lookup (data->active, SEND_URI_KEY); if (info == NULL) { info = g_malloc0 (sizeof (*info)); info->type = SEND_SEND; d(printf("adding dest %s\n", destination)); info->uri = g_strdup (destination); info->keep = FALSE; info->cancel = camel_operation_new (operation_status, info); info->state = SEND_ACTIVE; info->timeout_id = g_timeout_add (STATUS_TIMEOUT, operation_status_timeout, info); g_hash_table_insert (data->active, SEND_URI_KEY, info); list = g_list_prepend (list, info); } else if (info->timeout_id == 0) info->timeout_id = g_timeout_add (STATUS_TIMEOUT, operation_status_timeout, info); send_icon = e_icon_factory_get_image ( "mail-outbox", E_ICON_SIZE_LARGE_TOOLBAR); pretty_url = format_url (destination, NULL); label = gtk_label_new (NULL); gtk_label_set_ellipsize ( GTK_LABEL (label), PANGO_ELLIPSIZE_END); gtk_label_set_markup (GTK_LABEL (label), pretty_url); g_free (pretty_url); progress_bar = gtk_progress_bar_new (); cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL); status_label = gtk_label_new (_("Waiting...")); gtk_label_set_ellipsize ( GTK_LABEL (status_label), PANGO_ELLIPSIZE_END); gtk_misc_set_alignment (GTK_MISC (label), 0, .5); gtk_misc_set_alignment (GTK_MISC (status_label), 0, .5); gtk_table_attach ( GTK_TABLE (table), send_icon, 0, 1, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), label, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), progress_bar, 2, 3, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), cancel_button, 3, 4, row, row+2, 0, 0, 0, 0); gtk_table_attach ( GTK_TABLE (table), status_label, 1, 2, row+1, row+2, GTK_EXPAND | GTK_FILL, 0, 0, 0); info->progress_bar = progress_bar; info->cancel_button = cancel_button; info->data = data; info->status_label = status_label; g_signal_connect ( cancel_button, "clicked", G_CALLBACK (receive_cancel), info); gtk_widget_show_all (table); } gtk_widget_show (GTK_WIDGET (gd)); g_signal_connect (gd, "response", G_CALLBACK (dialog_response), data); g_object_weak_ref ((GObject *) gd, (GWeakNotify) dialog_destroy_cb, data); data->infos = list; data->gd = gd; return data; }
/* we setup the download info's in a hashtable, if we later need to build the gui, we insert them in to add them. */ void mail_receive_uri (const char *uri, int keep) { struct _send_info *info; struct _send_data *data; CamelFolder *outbox_folder; send_info_t type; data = setup_send_data(); info = g_hash_table_lookup(data->active, uri); if (info != NULL) { d(printf("download of %s still in progress\n", uri)); return; } d(printf("starting non-interactive download of '%s'\n", uri)); type = get_receive_type (uri); if (type == SEND_INVALID || type == SEND_SEND) { d(printf ("unsupported provider: '%s'\n", uri)); return; } info = g_malloc0 (sizeof (*info)); info->type = type; info->progress_bar = NULL; info->status_label = NULL; info->uri = g_strdup (uri); info->keep = keep; info->cancel = camel_operation_new (operation_status, info); info->cancel_button = NULL; info->data = data; info->state = SEND_ACTIVE; info->timeout_id = 0; d(printf("Adding new info %p\n", info)); g_hash_table_insert (data->active, info->uri, info); switch (info->type) { case SEND_RECEIVE: mail_fetch_mail (info->uri, info->keep, FILTER_SOURCE_INCOMING, info->cancel, receive_get_folder, info, receive_status, info, receive_done, info); break; case SEND_SEND: /* todo, store the folder in info? */ outbox_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX); mail_send_queue (outbox_folder, info->uri, FILTER_SOURCE_OUTGOING, info->cancel, receive_get_folder, info, receive_status, info, receive_done, info); break; case SEND_UPDATE: mail_get_store (info->uri, info->cancel, receive_update_got_store, info); break; default: g_return_if_reached(); } }
static struct _send_data * build_infra (EMailSession *session, gboolean allow_send) { struct _send_data *data; struct _send_info *info; CamelService *transport = NULL; GList *link; GList *list = NULL; GList *accounts=NULL; transport = ref_default_transport (session); accounts = mail_get_all_accounts(); data = setup_send_data (session); link = accounts; while (link) { ESource *source; CamelService *service; const gchar *uid; source = (ESource *)link->data; if (!e_source_get_enabled(source)) { link = link->next; continue; } uid = e_source_get_uid (source); service = camel_session_ref_service ( CAMEL_SESSION (session), uid); /* see if we have an outstanding download active */ info = g_hash_table_lookup (data->active, uid); if (info == NULL) { send_info_t type = SEND_INVALID; type = get_receive_type (service); if (type == SEND_INVALID || type == SEND_SEND) { link = link->next; continue; } info = g_malloc0 (sizeof (*info)); info->type = type; info->session = g_object_ref (session); d(printf("adding source %s\n", source->url)); info->service = g_object_ref (service); info->keep_on_server = mail_get_keep_on_server (service); info->cancellable = camel_operation_new (); info->state = allow_send ? SEND_ACTIVE : SEND_COMPLETE; info->timeout_id = g_timeout_add ( STATUS_TIMEOUT, operation_status_timeout, info); g_signal_connect ( info->cancellable, "status", G_CALLBACK (operation_status), info); g_hash_table_insert ( data->active, g_strdup(uid), info); list = g_list_prepend (list, info); } else if (info->timeout_id == 0) info->timeout_id = g_timeout_add ( STATUS_TIMEOUT, operation_status_timeout, info); info->data = data; link = link->next; } g_list_free_full (accounts, (GDestroyNotify) g_object_unref); /* Skip displaying the SMTP row if we've got no outbox, * outgoing account or unsent mails. */ CamelFolder *local_outbox; local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); if (allow_send && local_outbox && CAMEL_IS_TRANSPORT (transport) && (camel_folder_get_message_count (local_outbox) - camel_folder_get_deleted_message_count (local_outbox)) != 0) { info = g_hash_table_lookup (data->active, SEND_URI_KEY); if (info == NULL) { info = g_malloc0 (sizeof (*info)); info->type = SEND_SEND; info->service = g_object_ref (transport); info->keep_on_server = FALSE; info->cancellable = camel_operation_new (); info->state = SEND_ACTIVE; info->timeout_id = g_timeout_add ( STATUS_TIMEOUT, operation_status_timeout, info); g_signal_connect ( info->cancellable, "status", G_CALLBACK (operation_status), info); g_hash_table_insert (data->active, g_strdup(SEND_URI_KEY), info); list = g_list_prepend (list, info); } else if (info->timeout_id == 0) info->timeout_id = g_timeout_add ( STATUS_TIMEOUT, operation_status_timeout, info); info->data = data; } data->infos = list; return data; }
GCancellable * mail_send (EMailSession *session) { CamelFolder *local_outbox; CamelService *service; struct _send_info *info; struct _send_data *data; send_info_t type = SEND_INVALID; const gchar *transport_uid; ESource *account; const gchar *extension_name; account = e_source_registry_ref_default_mail_identity (source_registry); if (account == NULL) return NULL; extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION; if (e_source_has_extension (account, extension_name)) { ESourceMailSubmission *extension; gchar *uid; extension = e_source_get_extension (account, extension_name); uid = e_source_mail_submission_dup_transport_uid (extension); g_object_unref (account); account = e_source_registry_ref_source (source_registry, uid); g_free (uid); } else { g_object_unref (account); account = NULL; } if (account == NULL) return NULL; transport_uid = e_source_get_uid (account); data = setup_send_data (session); info = g_hash_table_lookup (data->active, SEND_URI_KEY); if (info != NULL) { info->again++; d(printf("send of %s still in progress\n", transport_uid)); return info->cancellable; } service = camel_session_ref_service ( CAMEL_SESSION (session), transport_uid); if (!CAMEL_IS_TRANSPORT (service)) { return NULL; } d(printf("starting non-interactive send of '%s'\n", account->transport->url)); type = get_receive_type (service); if (type == SEND_INVALID) { return NULL; } info = g_malloc0 (sizeof (*info)); info->type = SEND_SEND; info->session = g_object_ref (session); info->service = g_object_ref (service); info->keep_on_server = FALSE; info->cancellable = camel_operation_new(); info->data = data; info->state = SEND_ACTIVE; info->timeout_id = 0; d(printf("Adding new info %p\n", info)); g_hash_table_insert (data->active, g_strdup(SEND_URI_KEY), info); /* todo, store the folder in info? */ local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); mail_send_queue ( session, local_outbox, CAMEL_TRANSPORT (service), E_FILTER_SOURCE_OUTGOING, info->cancellable, receive_get_folder, info, receive_status, info, send_done, info); return info->cancellable; }
/* We setup the download info's in a hashtable, if we later * need to build the gui, we insert them in to add them. */ GCancellable * mail_receive_service (CamelService *service) { struct _send_info *info; struct _send_data *data; CamelFolder *local_outbox; const gchar *uid; EMailSession *session; send_info_t type = SEND_INVALID; g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL); session = (EMailSession *)camel_service_get_session (service); uid = camel_service_get_uid (service); data = setup_send_data (session); info = g_hash_table_lookup (data->active, uid); if (info != NULL) return info->cancellable; type = get_receive_type (service); if (type == SEND_INVALID || type == SEND_SEND) return NULL; info = g_malloc0 (sizeof (*info)); info->type = type; info->session = g_object_ref (session); info->service = g_object_ref (service); info->keep_on_server = mail_get_keep_on_server (service); info->cancellable = camel_operation_new (); info->data = data; info->state = SEND_ACTIVE; info->timeout_id = 0; g_signal_connect ( info->cancellable, "status", G_CALLBACK (operation_status), info); d(printf("Adding new info %p\n", info)); g_hash_table_insert (data->active, g_strdup(uid), info); switch (info->type) { case SEND_RECEIVE: mail_fetch_mail ( CAMEL_STORE (service), CAMEL_FETCH_OLD_MESSAGES, -1, E_FILTER_SOURCE_INCOMING, mail_provider_fetch_lock, mail_provider_fetch_unlock, mail_provider_fetch_inbox_folder, info->cancellable, receive_get_folder, info, receive_status, info, receive_done, info); break; case SEND_SEND: /* todo, store the folder in info? */ local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); mail_send_queue ( info->session, local_outbox, CAMEL_TRANSPORT (service), E_FILTER_SOURCE_OUTGOING, info->cancellable, receive_get_folder, info, receive_status, info, send_done, info); break; case SEND_UPDATE: receive_update_got_store (CAMEL_STORE (service), info); break; default: g_return_val_if_reached (NULL); } return info->cancellable; }