static void send_receive (EMailSession *session, gboolean allow_send) { CamelFolder *local_outbox; struct _send_data *data; GList *scan; if (send_data) /* Send Receive is already in progress */ return; if (!camel_session_get_online (CAMEL_SESSION (session))) return; local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); data = build_infra (session, allow_send); for (scan = data->infos; scan != NULL; scan = scan->next) { struct _send_info *info = scan->data; if (!CAMEL_IS_SERVICE (info->service)) continue; switch (info->type) { case SEND_RECEIVE: mail_fetch_mail ( CAMEL_STORE (info->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? */ mail_send_queue ( session, local_outbox, CAMEL_TRANSPORT (info->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 (info->service), info); break; default: break; } } return ; }
/* when receive/send is complete */ static void receive_done (gint still_more, gpointer data) { struct _send_info *info = data; const gchar *uid; uid = camel_service_get_uid (info->service); g_return_if_fail (uid != NULL); /* if we've been called to run again - run again */ if (info->type == SEND_SEND && info->state == SEND_ACTIVE && info->again) { EMailSession *session; CamelFolder *local_outbox; session = info->session; local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); g_return_if_fail (CAMEL_IS_TRANSPORT (info->service)); info->again = 0; mail_send_queue ( info->session, local_outbox, CAMEL_TRANSPORT (info->service), E_FILTER_SOURCE_OUTGOING, info->cancellable, receive_get_folder, info, receive_status, info, send_done, info); return; } //FIXME Set SEND completed here /* if (info->state == SEND_CANCELLED) text = _("Canceled."); else { text = _("Complete."); info->state = SEND_COMPLETE; } */ /* remove/free this active download */ d(printf("%s: freeing info %p\n", G_STRFUNC, info)); if (info->type == SEND_SEND) g_hash_table_steal (info->data->active, SEND_URI_KEY); else g_hash_table_steal (info->data->active, uid); info->data->infos = g_list_remove (info->data->infos, info); if (g_hash_table_size (info->data->active) == 0) { //FIXME: THIS MEANS SEND RECEIVE IS COMPLETED free_send_data (); } free_send_info (info); }
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); }
/* when receive/send is complete */ static void receive_done (char *uri, void *data) { struct _send_info *info = data; /* if we've been called to run again - run again */ if (info->type == SEND_SEND && info->state == SEND_ACTIVE && info->again) { info->again = 0; mail_send_queue (mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX), info->uri, FILTER_SOURCE_OUTGOING, info->cancel, receive_get_folder, info, receive_status, info, receive_done, info); return; } if (info->progress_bar) { const gchar *text; gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR (info->progress_bar), 1.0); if (info->state == SEND_CANCELLED) text = _("Canceled."); else { text = _("Complete."); info->state = SEND_COMPLETE; } gtk_label_set_text (GTK_LABEL (info->status_label), text); } if (info->cancel_button) gtk_widget_set_sensitive (info->cancel_button, FALSE); /* remove/free this active download */ d(printf("%s: freeing info %p\n", G_STRFUNC, info)); if (info->type == SEND_SEND) g_hash_table_steal(info->data->active, SEND_URI_KEY); else g_hash_table_steal(info->data->active, info->uri); info->data->infos = g_list_remove(info->data->infos, info); if (g_hash_table_size(info->data->active) == 0) { if (info->data->gd) gtk_widget_destroy((GtkWidget *)info->data->gd); free_send_data(); } free_send_info(info); }
GtkWidget * mail_send_receive (void) { CamelFolder *outbox_folder; struct _send_data *data; EAccountList *accounts; EAccount *account; GList *scan; if (send_recv_dialog != NULL) { if (GTK_WIDGET_REALIZED(send_recv_dialog)) { gdk_window_show(send_recv_dialog->window); gdk_window_raise(send_recv_dialog->window); } return send_recv_dialog; } if (!camel_session_is_online (session)) return send_recv_dialog; account = mail_config_get_default_account (); if (!account || !account->transport->url) return send_recv_dialog; accounts = mail_config_get_accounts (); outbox_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX); data = build_dialog (accounts, outbox_folder, account->transport->url); scan = data->infos; while (scan) { struct _send_info *info = scan->data; 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? */ 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: break; } scan = scan->next; } return send_recv_dialog; }
/* 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(); } }
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; }