+* 2008-W20:
+- a couple of send and receive related issues fixed
+
+* 2008-W19:
+- a couple of rare hangs / crashes fixed
+
* 2008-W18:
- some more low-memory fixes
- many small UI issues were fixed
+modest (1.0-2008.20-1) hardy; urgency=low
+
+ * Fixes: NB#84005, NB#84821, NB#84823, NB#84832, NB#85028, NB#85030
+ * Fixes: NB#85055, NB#79005, NB#81913, NB#84054, NB#84260, NB#84604
+ * Fixes: NB#84714, NB#84731, NB#85062, NB#85108, NB#85131, NB#84764
+ * Fixes: NB#84922, NB#83343, NB#84828, NB#85031, NB#84551
+
+ -- Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com> Mon, 12 May 2008 19:09:20 +0300
+
modest (1.0-2008.19-1) hardy; urgency=low
* Fixes: NB#84764, NB#84922, NB#84551, NB#84828, NB#83343
}
static gboolean
-on_hide_opening_animation (gpointer userdata)
+on_find_msg_async_destroy (gpointer userdata)
{
OpenMsgPerformerInfo *info = (OpenMsgPerformerInfo *) userdata;
info->animation = NULL;
}
+ if (info->uri)
+ g_free (info->uri);
+
+ if (info->account)
+ g_object_unref (info->account);
+
g_slice_free (OpenMsgPerformerInfo, info);
return FALSE;
}
+static void
+find_msg_async_cb (TnyFolder *folder,
+ gboolean cancelled,
+ TnyMsg *msg,
+ GError *err,
+ gpointer user_data)
+{
+ TnyHeader *header;
+ gchar *msg_uid;
+ ModestWindowMgr *win_mgr;
+ ModestWindow *msg_view = NULL;
+ gboolean is_draft = FALSE;
+ OpenMsgPerformerInfo *info = (OpenMsgPerformerInfo *) user_data;
+
+ if (err || cancelled) {
+ g_idle_add (notify_msg_not_found_in_idle, NULL);
+ goto end;
+ }
+
+ header = tny_msg_get_header (msg);
+ if (header && (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED)) {
+ g_object_unref (header);
+ g_object_unref (msg);
+ g_idle_add (notify_msg_not_found_in_idle, NULL);
+ goto end;
+ }
+
+ msg_uid = modest_tny_folder_get_header_unique_id (header);
+ win_mgr = modest_runtime_get_window_mgr ();
+
+ if (modest_tny_folder_is_local_folder (folder) &&
+ (modest_tny_folder_get_local_or_mmc_folder_type (folder) == TNY_FOLDER_TYPE_DRAFTS)) {
+ is_draft = TRUE;
+ }
+
+ if (modest_window_mgr_find_registered_header (win_mgr, header, &msg_view)) {
+ gtk_window_present (GTK_WINDOW(msg_view));
+ } else {
+ const gchar *modest_account_name;
+ TnyAccount *account;
+
+ modest_window_mgr_register_header (win_mgr, header, NULL);
+
+ account = tny_folder_get_account (folder);
+ if (account) {
+ modest_account_name =
+ modest_tny_account_get_parent_modest_account_name_for_server_account (account);
+ } else {
+ modest_account_name = NULL;
+ }
+
+ /* Drafts will be opened in the editor, and others will be opened in the viewer */
+ if (is_draft) {
+ gchar *modest_account_name = NULL;
+ gchar *from_header;
+
+ /* we cannot edit without a valid account... */
+ if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr (), TRUE)) {
+ if (!modest_ui_actions_run_account_setup_wizard(NULL)) {
+ modest_window_mgr_unregister_header (win_mgr,
+ header);
+ goto cleanup;
+ }
+ }
+
+ from_header = tny_header_dup_from (header);
+ if (from_header) {
+ GSList *accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
+ GSList *node = NULL;
+ for (node = accounts; node != NULL; node = g_slist_next (node)) {
+ gchar *from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr (), node->data);
+
+ if (from && (strcmp (from_header, from) == 0)) {
+ g_free (modest_account_name);
+ modest_account_name = g_strdup (node->data);
+ g_free (from);
+ break;
+ }
+ g_free (from);
+ }
+ g_slist_foreach (accounts, (GFunc) g_free, NULL);
+ g_slist_free (accounts);
+ g_free (from_header);
+ }
+
+ if (modest_account_name == NULL) {
+ modest_account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
+ }
+ msg_view = modest_msg_edit_window_new (msg, modest_account_name, TRUE);
+ g_free (modest_account_name);
+ } else {
+ TnyHeader *header;
+ const gchar *modest_account_name;
+
+ if (account) {
+ modest_account_name =
+ modest_tny_account_get_parent_modest_account_name_for_server_account (account);
+ } else {
+ modest_account_name = NULL;
+ }
+
+ header = tny_msg_get_header (msg);
+ msg_view = modest_msg_view_window_new_for_search_result (msg, modest_account_name, msg_uid);
+ if (! (tny_header_get_flags (header) & TNY_HEADER_FLAG_SEEN)) {
+ ModestMailOperation *mail_op;
+
+ tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
+ /* Sync folder, we need this to save the seen flag */
+ mail_op = modest_mail_operation_new (NULL);
+ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+ mail_op);
+ modest_mail_operation_sync_folder (mail_op, folder, FALSE);
+ g_object_unref (mail_op);
+ }
+ g_object_unref (header);
+ }
+
+ if (msg_view != NULL) {
+ modest_window_mgr_register_window (win_mgr, msg_view);
+ gtk_widget_show_all (GTK_WIDGET (msg_view));
+ }
+ }
+
+cleanup:
+ g_object_unref (header);
+ g_object_unref (msg);
+
+end:
+ on_find_msg_async_destroy (info);
+}
+
+
static void
on_open_message_performer (gboolean canceled,
GError *err,
gpointer user_data)
{
OpenMsgPerformerInfo *info;
- gchar *uri;
- TnyHeader *header;
- gchar *msg_uid;
- ModestWindowMgr *win_mgr;
- ModestWindow *msg_view = NULL;
- gboolean is_draft = FALSE;
TnyFolder *folder = NULL;
- TnyMsg *msg = NULL;
info = (OpenMsgPerformerInfo *) user_data;
- uri = info->uri;
-
- if (canceled || err) {
- goto frees;
- }
-
- /* Get folder */
- if (!account) {
- ModestTnyAccountStore *account_store;
- ModestTnyLocalFoldersAccount *local_folders_account;
-
- account_store = modest_runtime_get_account_store ();
- local_folders_account = MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (
- modest_tny_account_store_get_local_folders_account (account_store));
- folder = modest_tny_local_folders_account_get_merged_outbox (local_folders_account);
- g_object_unref (local_folders_account);
- } else {
- folder = tny_store_account_find_folder (TNY_STORE_ACCOUNT (account), uri, NULL);
- }
-
-
- if (!folder) {
- g_idle_add (notify_msg_not_found_in_idle, NULL);
- goto frees;
- }
-
- if (modest_tny_folder_is_local_folder (folder) &&
- (modest_tny_folder_get_local_or_mmc_folder_type (folder) == TNY_FOLDER_TYPE_DRAFTS)) {
- is_draft = TRUE;
- }
-
- /* Get message */
- msg = tny_folder_find_msg (folder, uri, NULL);
- if (!msg) {
- g_idle_add (notify_msg_not_found_in_idle, NULL);
- goto frees;
- }
-
- header = tny_msg_get_header (msg);
- if (header && (tny_header_get_flags (header)&TNY_HEADER_FLAG_DELETED)) {
- g_object_unref (header);
- g_object_unref (msg);
- g_idle_add (notify_msg_not_found_in_idle, NULL);
- goto frees;
- }
- msg_uid = modest_tny_folder_get_header_unique_id (header);
- win_mgr = modest_runtime_get_window_mgr ();
-
- if (modest_window_mgr_find_registered_header (win_mgr, header, &msg_view)) {
- gtk_window_present (GTK_WINDOW(msg_view));
- } else {
- const gchar *modest_account_name;
-
- /* g_debug ("creating new window for this msg"); */
- modest_window_mgr_register_header (win_mgr, header, NULL);
-
- if (account) {
- modest_account_name =
- modest_tny_account_get_parent_modest_account_name_for_server_account (account);
- } else {
- modest_account_name = NULL;
- }
-
- /* Drafts will be opened in the editor, and others will be opened in the viewer */
- if (is_draft) {
- msg_view = modest_msg_edit_window_new (msg, modest_account_name, TRUE);
- } else {
- TnyHeader *header;
- header = tny_msg_get_header (msg);
- msg_view = modest_msg_view_window_new_for_search_result (msg, modest_account_name, msg_uid);
- if (! (tny_header_get_flags (header) & TNY_HEADER_FLAG_SEEN))
- tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
- g_object_unref (header);
-
- }
- modest_window_mgr_register_window (win_mgr, msg_view);
- gtk_widget_show_all (GTK_WIDGET (msg_view));
- }
- g_object_unref (header);
- g_object_unref (msg);
- g_object_unref (folder);
-
- frees:
- g_free (info->uri);
- if (info->account)
- g_object_unref (info->account);
- g_idle_add (on_hide_opening_animation, info);
+ if (canceled || err) {
+ g_idle_add (notify_msg_not_found_in_idle, NULL);
+ on_find_msg_async_destroy (info);
+ return;
+ }
+
+ /* Get folder */
+ if (!account) {
+ ModestTnyAccountStore *account_store;
+ ModestTnyLocalFoldersAccount *local_folders_account;
+
+ account_store = modest_runtime_get_account_store ();
+ local_folders_account = MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (
+ modest_tny_account_store_get_local_folders_account (account_store));
+ folder = modest_tny_local_folders_account_get_merged_outbox (local_folders_account);
+ g_object_unref (local_folders_account);
+ } else {
+ folder = tny_store_account_find_folder (TNY_STORE_ACCOUNT (account), info->uri, NULL);
+ }
+ if (!folder) {
+ g_idle_add (notify_msg_not_found_in_idle, NULL);
+ on_find_msg_async_destroy (info);
+ return;
+ }
+
+ info->animation_timeout = g_timeout_add (1000, on_show_opening_animation, info);
+ /* Get message */
+ tny_folder_find_msg_async (folder, info->uri, find_msg_async_cb, NULL, info);
+ g_object_unref (folder);
}
static gboolean
info->account = g_object_ref (account);
info->uri = uri;
info->connect = TRUE;
- info->animation_timeout = g_timeout_add (1000, on_show_opening_animation, info);
+ info->animation = NULL;
+ info->animation_timeout = 0;
/* Try to get the message, if it's already downloaded
we don't need to connect */
g_object_unref (local_folders_account);
}
if (folder) {
- TnyMsg *msg = tny_folder_find_msg (folder, uri, NULL);
- if (msg) {
- info->connect = FALSE;
- g_object_unref (msg);
+ TnyDevice *device;
+ gboolean device_online;
+
+ device = modest_runtime_get_device();
+ device_online = tny_device_is_online (device);
+ if (device_online) {
+ info->connect = TRUE;
+ } else {
+ TnyMsg *msg = tny_folder_find_msg (folder, uri, NULL);
+ if (msg) {
+ info->connect = FALSE;
+ g_object_unref (msg);
+ } else {
+ info->connect = TRUE;
+ }
}
g_object_unref (folder);
}
{
modest_platform_run_information_dialog (NULL, _("mail_ni_ui_folder_get_msg_folder_error"), FALSE);
+ g_idle_add (notify_error_in_dbus_callback, NULL);
+
return FALSE;
}
#define CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW, ModestConnectionSpecificSmtpEditWindowPrivate))
+static void on_response (GtkDialog *dialog,
+ gint arg1,
+ gpointer user_data);
+
typedef struct _ModestConnectionSpecificSmtpEditWindowPrivate ModestConnectionSpecificSmtpEditWindowPrivate;
struct _ModestConnectionSpecificSmtpEditWindowPrivate
gtk_editable_select_region (GTK_EDITABLE (priv->entry_outgoingserver), 0, -1);
return;
}
+ } else {
+ /* Ask user if they want to discard changes */
+ if (priv->is_dirty) {
+ gint response;
+ response = modest_platform_run_confirmation_dialog (GTK_WINDOW (user_data),
+ _("imum_nc_wizard_confirm_lose_changes"));
+ if (response == GTK_RESPONSE_CANCEL)
+ g_signal_stop_emission_by_name (dialog, "response");
+ }
}
-
}
static void on_set_focus_child (GtkContainer *container, GtkWidget *widget, gpointer user_data)
return server_settings;
}
-gboolean modest_connection_specific_smtp_edit_window_is_dirty(
- ModestConnectionSpecificSmtpEditWindow *window)
+gboolean
+modest_connection_specific_smtp_edit_window_is_dirty(ModestConnectionSpecificSmtpEditWindow *window)
{
ModestConnectionSpecificSmtpEditWindowPrivate *priv =
CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (window);
server_settings = NULL;
}
- gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (self));
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (window));
gboolean dialog_finished = FALSE;
while (!dialog_finished)
GtkWidget *find_toolbar;
gchar *last_search;
+ GtkWidget *font_dialog;
+
GtkWidget *scroll;
guint scroll_drag_timeout_id;
gdouble last_upper;
priv->scroll_drag_timeout_id = 0;
priv->last_upper = 0.0;
+ priv->font_dialog = NULL;
+
modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
GTK_WINDOW(obj),"applications_email_editor");
call this function before */
modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
+ if (priv->font_dialog != NULL) {
+ gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
+ }
+
if (priv->clipboard_text != NULL) {
g_free (priv->clipboard_text);
priv->clipboard_text = NULL;
NULL);
gtk_widget_show_all (dialog);
+ priv->font_dialog = dialog;
response = gtk_dialog_run (GTK_DIALOG (dialog));
+ priv->font_dialog = NULL;
if (response == GTK_RESPONSE_OK) {
g_object_get( dialog,
G_CALLBACK (entry_changed),
dialog);
+
+ /* Some locales like pt_BR need this to get the full window
+ title shown */
+ gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
+
/* Create the hbox */
hbox = gtk_hbox_new (FALSE, 12);
- gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
/* Add hbox to dialog */
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
hbox, FALSE, FALSE, 0);
-
- gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
- gtk_window_set_transient_for (GTK_WINDOW (dialog), parent_window);
-
- /* Some locales like pt_BR need this to get the full window
- title shown */
- gtk_widget_set_size_request (GTK_WIDGET (dialog), 300, -1);
+ modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
+ GTK_WINDOW (dialog));
+ gtk_widget_show_all (GTK_WIDGET(dialog));
result = gtk_dialog_run (GTK_DIALOG(dialog));
if (result == GTK_RESPONSE_ACCEPT)
MODEST_MAIL_OPERATION_ERROR_RETRIEVAL_NUMBER_LIMIT, /* There were too many messages to retrieve. */
MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED,
MODEST_MAIL_OPERATION_ERROR_FILE_IO, /* couldn't retrieve a file to construct a mail */
+ MODEST_MAIL_OPERATION_ERROR_SEND_QUEUE_ADD_ERROR,
} ModestErrorCode;
G_END_DECLS
/* ************************** SEND ACTIONS ************************* */
/* ******************************************************************* */
+static void
+send_mail_on_added_to_outbox (TnySendQueue *send_queue,
+ gboolean cancelled,
+ TnyMsg *msg,
+ GError *err,
+ gpointer user_data)
+{
+ ModestMailOperationPrivate *priv;
+ ModestMailOperation *self;
+
+ self = MODEST_MAIL_OPERATION (user_data);
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ if (cancelled || err)
+ goto end;
+
+ if (err) {
+ g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+ MODEST_MAIL_OPERATION_ERROR_SEND_QUEUE_ADD_ERROR,
+ "Error adding a msg to the send queue\n");
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS;
+ } else {
+ priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+ }
+ end:
+ modest_mail_operation_notify_end (self);
+ g_object_unref (self);
+}
+
void
modest_mail_operation_send_mail (ModestMailOperation *self,
TnyTransportAccount *transport_account,
"modest: could not find send queue for account\n");
priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
modest_mail_operation_notify_end (self);
-
} else {
- /* Add the msg to the queue */
modest_mail_operation_notify_start (self);
-
- tny_send_queue_add_async (send_queue, msg, NULL, NULL, NULL);
- modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue), FALSE);
-
- if (priv->error) {
- priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS;
- } else {
- priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
- }
- modest_mail_operation_notify_end (self);
+ /* Add the msg to the queue. The callback will
+ finalize the mail operation */
+ tny_send_queue_add_async (send_queue, msg, send_mail_on_added_to_outbox,
+ NULL, g_object_ref (self));
+ modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue),
+ FALSE);
}
-
}
helper->dest_folder = g_object_ref(folder);
helper->user_callback = user_callback;
helper->user_data = user_data;
- helper->delete = delete_original;
helper->last_total_bytes = 0;
helper->sum_total_bytes = 0;
helper->total_bytes = compute_message_list_size (headers);
leave_on_server = FALSE;
}
+ /* Do not delete messages if leave on server is TRUE */
+ helper->delete = (leave_on_server) ? FALSE : delete_original;
+
modest_mail_operation_notify_start (self);
tny_folder_transfer_msgs_async (src_folder,
helper->headers,
folder,
- (leave_on_server) ? FALSE : delete_original,
+ helper->delete,
transfer_msgs_cb,
transfer_msgs_status_cb,
helper);
gboolean found = FALSE;
/* Do not search into attachments */
- if (modest_tny_mime_part_is_attachment_for_modest (part))
+ if (modest_tny_mime_part_is_attachment_for_modest (part) && !TNY_IS_MSG (part))
return FALSE;
#ifdef MODEST_HAVE_OGS
/* no parts? assume it's single-part message */
if (tny_iterator_is_done(iter)) {
- const gchar *content_type;
+ gchar *content_type;
+ gchar *content_type_lower;
+ gboolean is_text_part;
g_object_unref (G_OBJECT(iter));
- content_type = tny_mime_part_get_content_type (msg);
+ content_type = g_strdup (tny_mime_part_get_content_type (msg));
+ if (content_type == NULL)
+ return NULL;
+ content_type = g_strstrip (content_type);
+ content_type_lower = g_ascii_strdown (content_type, -1);
+ g_free (content_type);
+ is_text_part = g_str_has_prefix (content_type_lower, "text/");
+ g_free (content_type_lower);
/* if this part cannot be a supported body return NULL */
- if (!g_str_has_prefix (content_type, "text/")) {
+ if (!is_text_part) {
return NULL;
} else {
return TNY_MIME_PART (g_object_ref(G_OBJECT(msg)));
return str;
}
+typedef struct {
+ TnySendQueueAddCallback callback;
+ gpointer user_data;
+} AddAsyncHelper;
+
static void
_on_added_to_outbox (TnySendQueue *self,
gboolean cancelled,
SendInfo *info = NULL;
GList* existing = NULL;
gchar* msg_id = NULL;
+ AddAsyncHelper *helper;
g_return_if_fail (TNY_IS_SEND_QUEUE(self));
g_return_if_fail (TNY_IS_CAMEL_MSG(msg));
end:
g_object_unref (G_OBJECT(header));
+
+ /* Call the user callback */
+ helper = (AddAsyncHelper *) user_data;
+ if (helper->callback)
+ helper->callback (self, cancelled, msg, err, helper->user_data);
+ g_slice_free (AddAsyncHelper, helper);
}
static void
break;
/* Add new meesage info */
- info = g_slice_new (SendInfo);
+ info = g_slice_new0 (SendInfo);
info->msg_id = strdup(msg_uid);
info->status = MODEST_TNY_SEND_QUEUE_WAITING;
g_queue_push_tail (priv->queue, info);
TnyStatusCallback status_callback,
gpointer user_data)
{
+ AddAsyncHelper *helper = g_slice_new0 (AddAsyncHelper);
+ helper->callback = callback;
+ helper->user_data = user_data;
+
/* Call the superclass passing our own callback */
- TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->add_async (self, msg, _on_added_to_outbox, NULL, NULL);
+ TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->add_async (self, msg,
+ _on_added_to_outbox,
+ status_callback,
+ helper);
}
G_OBJECT_CLASS(parent_class)->finalize (obj);
}
+typedef struct {
+ TnyCamelTransportAccount *account;
+ ModestTnySendQueue *queue;
+} GetHeadersInfo;
+
+static void
+new_queue_get_headers_async_cb (TnyFolder *folder,
+ gboolean cancelled,
+ TnyList *headers,
+ GError *err,
+ gpointer user_data)
+{
+ ModestTnySendQueue *self;
+ TnyIterator *iter;
+ GetHeadersInfo *info;
+
+ info = (GetHeadersInfo *) user_data;
+ self = MODEST_TNY_SEND_QUEUE (info->queue);
+
+ /* In case of error set the transport account anyway */
+ if (cancelled || err)
+ goto set_transport;
+
+ /* Add messages to our internal queue */
+ iter = tny_list_create_iterator (headers);
+ while (!tny_iterator_is_done (iter)) {
+ TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
+ _add_message (self, header);
+ g_object_unref (header);
+ tny_iterator_next (iter);
+ }
+
+ /* Reenable suspended items */
+ modest_tny_send_queue_wakeup (self);
+
+ /* Frees */
+ g_object_unref (iter);
+ g_object_unref (headers);
+
+ set_transport:
+ /* Do this at the end, because it'll call tny_send_queue_flush
+ which will call tny_send_queue_get_outbox and
+ tny_send_queue_get_sentbox */
+ tny_camel_send_queue_set_transport_account (TNY_CAMEL_SEND_QUEUE(self),
+ info->account);
+
+ /* Frees */
+ g_object_unref (info->account);
+ g_object_unref (info->queue);
+ g_slice_free (GetHeadersInfo, info);
+}
+
ModestTnySendQueue*
modest_tny_send_queue_new (TnyCamelTransportAccount *account)
{
ModestTnySendQueue *self = NULL;
ModestTnySendQueuePrivate *priv = NULL;
- TnyIterator *iter = NULL;
TnyList *headers = NULL;
+ GetHeadersInfo *info;
g_return_val_if_fail (TNY_IS_CAMEL_TRANSPORT_ACCOUNT(account), NULL);
TNY_FOLDER_TYPE_OUTBOX);
priv->sentbox = modest_tny_account_get_special_folder (TNY_ACCOUNT(account),
TNY_FOLDER_TYPE_SENT);
-
priv->requested_send_receive = FALSE;
-
- headers = tny_simple_list_new ();
- tny_folder_get_headers (priv->outbox, headers, TRUE, NULL);
-
- /* Add messages to our internal queue */
- iter = tny_list_create_iterator (headers);
- while (!tny_iterator_is_done (iter)) {
- TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
- _add_message (self, header);
- g_object_unref (header);
-
- tny_iterator_next (iter);
- }
-
- /* Reenable suspended items */
- modest_tny_send_queue_wakeup (self);
-
- /* Frees */
- g_object_unref (headers);
- g_object_unref (iter);
-
- /* Do this at the end, because it'll call tny_send_queue_flush
- which will call tny_send_queue_get_outbox and
- tny_send_queue_get_sentbox */
- tny_camel_send_queue_set_transport_account (TNY_CAMEL_SEND_QUEUE(self),
- account);
+ headers = tny_simple_list_new ();
+ info = g_slice_new0 (GetHeadersInfo);
+ info->account = g_object_ref (account);
+ info->queue = g_object_ref (self);
+ tny_folder_get_headers_async (priv->outbox, headers, TRUE,
+ new_queue_get_headers_async_cb,
+ NULL, info);
return self;
}
tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
+ tny_folder_sync_async (priv->sentbox, FALSE, NULL, NULL, NULL);
+
/* Get status info */
item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id);
return status;
}
-void
-modest_tny_send_queue_wakeup (ModestTnySendQueue *self)
+static void
+wakeup_get_headers_async_cb (TnyFolder *folder,
+ gboolean cancelled,
+ TnyList *headers,
+ GError *err,
+ gpointer user_data)
{
+ ModestTnySendQueue *self;
ModestTnySendQueuePrivate *priv;
- TnyList *headers;
TnyIterator *iter;
- g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self));
-
+ self = MODEST_TNY_SEND_QUEUE (user_data);
priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
- headers = tny_simple_list_new ();
- tny_folder_get_headers (priv->outbox, headers, TRUE, NULL);
+ if (cancelled || err) {
+ g_debug ("Failed to wake up the headers of the send queue");
+ g_object_unref (self);
+ return;
+ }
/* Wake up every single suspended header */
iter = tny_list_create_iterator (headers);
/* Frees */
g_object_unref (iter);
- g_object_unref (G_OBJECT (headers));
+ g_object_unref (headers);
+ g_object_unref (self);
+}
+
+
+void
+modest_tny_send_queue_wakeup (ModestTnySendQueue *self)
+{
+ ModestTnySendQueuePrivate *priv;
+ TnyList *headers;
+
+ g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self));
+
+ priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
+
+ headers = tny_simple_list_new ();
+ tny_folder_get_headers_async (priv->outbox, headers, TRUE,
+ wakeup_get_headers_async_cb,
+ NULL, g_object_ref (self));
}
gboolean
} else {
/* Show the list of accounts */
GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
- gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
/* The accounts dialog must be modal */
modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
if (from_header) {
GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
GSList *node = NULL;
+ gchar *from_header_email;
+
+ from_header_email = modest_text_utils_get_email_address ((const gchar *) from_header);
+
for (node = accounts; node != NULL; node = g_slist_next (node)) {
- gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
+ gchar *from, *from_email;
- if (from && (strcmp (from_header, from) == 0)) {
- g_free (account);
- account = g_strdup (node->data);
+ from = modest_account_mgr_get_from_string (mgr, node->data);
+ if (from) {
+ from_email = modest_text_utils_get_email_address ((const gchar *) from);
+ if (strcmp (from_header_email, from_email) == 0) {
+ g_free (account);
+ account = g_strdup (node->data);
+ g_free (from);
+ break;
+ }
g_free (from);
- break;
}
- g_free (from);
}
+ g_free (from_header_email);
g_free (from_header);
g_slist_foreach (accounts, (GFunc) g_free, NULL);
g_slist_free (accounts);
}
+static gboolean
+same_account_selected (ModestFolderView *self,
+ TnyAccount *account)
+{
+ ModestFolderViewPrivate *priv;
+ gboolean same_account = FALSE;
+
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+ if (priv->cur_folder_store) {
+ TnyAccount *selected_folder_account = NULL;
+
+ if (TNY_IS_FOLDER (priv->cur_folder_store)) {
+ selected_folder_account =
+ tny_folder_get_account (TNY_FOLDER (priv->cur_folder_store));
+ } else {
+ selected_folder_account =
+ TNY_ACCOUNT (g_object_ref (priv->cur_folder_store));
+ }
+
+ if (selected_folder_account == account)
+ same_account = TRUE;
+
+ g_object_unref (selected_folder_account);
+ }
+ return same_account;
+}
+
+/**
+ *
+ * Selects the first inbox or the local account in an idle
+ */
+static gboolean
+on_idle_select_first_inbox_or_local (gpointer user_data)
+{
+ ModestFolderView *self = MODEST_FOLDER_VIEW (user_data);
+
+ gdk_threads_enter ();
+ modest_folder_view_select_first_inbox_or_local (self);
+ gdk_threads_leave ();
+
+ return FALSE;
+}
+
static void
on_account_changed (TnyAccountStore *account_store,
TnyAccount *tny_account,
gpointer user_data)
{
+ ModestFolderView *self;
ModestFolderViewPrivate *priv;
GtkTreeModel *sort_model, *filter_model;
GtkTreeSelection *sel;
+ gboolean same_account;
/* Ignore transport account insertions, we're not showing them
in the folder view */
return;
}
-
+ self = MODEST_FOLDER_VIEW (user_data);
priv = MODEST_FOLDER_VIEW_GET_PRIVATE (user_data);
/* Get the inner model */
return;
}
-
sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
if (!GTK_IS_TREE_MODEL_SORT(sort_model)) {
g_warning ("BUG: %s: not a valid sort model", __FUNCTION__);
return;
}
- /* Unselect the folder, clear the header list */
- sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (user_data));
- gtk_tree_selection_unselect_all (sel);
+ /* Invalidate the cur_folder_store only if the selected folder
+ belongs to the account that is being removed */
+ same_account = same_account_selected (self, tny_account);
+ if (same_account) {
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+ gtk_tree_selection_unselect_all (sel);
+ }
/* Remove the account from the model */
tny_list_remove (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
/* Refilter the model */
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
-}
-/**
- *
- * Selects the first inbox or the local account in an idle
- */
-static gboolean
-on_idle_select_first_inbox_or_local (gpointer user_data)
-{
- ModestFolderView *self = MODEST_FOLDER_VIEW (user_data);
-
- gdk_threads_enter ();
- modest_folder_view_select_first_inbox_or_local (self);
- gdk_threads_leave ();
-
- return FALSE;
+ /* Select the first INBOX if the currently selected folder
+ belongs to the account that is being deleted */
+ if (same_account)
+ g_idle_add (on_idle_select_first_inbox_or_local, self);
}
-
static void
on_account_removed (TnyAccountStore *account_store,
TnyAccount *account,
ModestFolderViewPrivate *priv;
GtkTreeModel *sort_model, *filter_model;
GtkTreeSelection *sel = NULL;
- gboolean same_account_selected = FALSE;
+ gboolean same_account = FALSE;
/* Ignore transport account removals, we're not showing them
in the folder view */
/* Invalidate the cur_folder_store only if the selected folder
belongs to the account that is being removed */
- if (priv->cur_folder_store) {
- TnyAccount *selected_folder_account = NULL;
-
- if (TNY_IS_FOLDER (priv->cur_folder_store)) {
- selected_folder_account =
- tny_folder_get_account (TNY_FOLDER (priv->cur_folder_store));
- } else {
- selected_folder_account =
- TNY_ACCOUNT (g_object_ref (priv->cur_folder_store));
- }
-
- if (selected_folder_account == account) {
- sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
- gtk_tree_selection_unselect_all (sel);
- same_account_selected = TRUE;
- }
- g_object_unref (selected_folder_account);
+ same_account = same_account_selected (self, account);
+ if (same_account) {
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+ gtk_tree_selection_unselect_all (sel);
}
/* Invalidate row to select only if the folder to select
/* Select the first INBOX if the currently selected folder
belongs to the account that is being deleted */
- if (same_account_selected)
+ if (same_account)
g_idle_add (on_idle_select_first_inbox_or_local, self);
}
}
static void
-modest_header_view_set_folder_intern (ModestHeaderView *self, TnyFolder *folder)
+set_folder_intern_get_headers_async_cb (TnyFolder *folder,
+ gboolean cancelled,
+ TnyList *headers,
+ GError *err,
+ gpointer user_data)
{
- TnyFolderType type;
- TnyList *headers;
+ ModestHeaderView *self;
ModestHeaderViewPrivate *priv;
- GList *cols, *cursor;
- GtkTreeModel *filter_model, *sortable;
- guint sort_colid;
- GtkSortType sort_type;
- priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
-
- headers = TNY_LIST (tny_gtk_header_list_model_new ());
+ g_return_if_fail (MODEST_IS_HEADER_VIEW (user_data));
- tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL(headers),
- folder, FALSE, NULL, NULL, NULL);
+ self = MODEST_HEADER_VIEW (user_data);
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
/* Add IDLE observer (monitor) and another folder observer for
new messages (self) */
tny_folder_monitor_add_list (priv->monitor, TNY_LIST (headers));
tny_folder_monitor_start (priv->monitor);
g_mutex_unlock (priv->observers_lock);
+}
+
+static void
+modest_header_view_set_folder_intern (ModestHeaderView *self, TnyFolder *folder)
+{
+ TnyFolderType type;
+ TnyList *headers;
+ ModestHeaderViewPrivate *priv;
+ GList *cols, *cursor;
+ GtkTreeModel *filter_model, *sortable;
+ guint sort_colid;
+ GtkSortType sort_type;
+
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+ headers = TNY_LIST (tny_gtk_header_list_model_new ());
+
+ /* Start the monitor in the callback of the
+ tny_gtk_header_list_model_set_folder call. It's crucial to
+ do it there and not just after the call because we want the
+ monitor to observe only the headers returned by the
+ tny_folder_get_headers_async call that it's inside the
+ tny_gtk_header_list_model_set_folder call. This way the
+ monitor infrastructure could successfully cope with
+ duplicates. For example if a tny_folder_add_msg_async is
+ happening while tny_gtk_header_list_model_set_folder is
+ invoked, then the first call could add a header that will
+ be added again by tny_gtk_header_list_model_set_folder, so
+ we'd end up with duplicate headers. sergio */
+ tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL(headers),
+ folder, FALSE,
+ set_folder_intern_get_headers_async_cb,
+ NULL, self);
sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(headers));
g_object_unref (G_OBJECT (headers));