X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-ui-actions.c;h=77121731568205d76e7ce3fbafacee36dda057f3;hp=3cef81bd6c21e4f73e757cee4c296d7a78db74bf;hb=d35c9918f4df9384dee13049f7d3344a47227f22;hpb=e422cdb3165a24a2cbd2f640dc9784f06835223d diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index 3cef81b..7712173 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -102,6 +102,7 @@ typedef struct _ReplyForwardHelper { ReplyForwardAction action; gchar *account_name; GtkWidget *parent_window; + TnyHeader *header; } ReplyForwardHelper; typedef struct _MoveToHelper { @@ -164,11 +165,6 @@ static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store); -static void transfer_messages_helper (GtkWindow *win, - TnyFolder *src_folder, - TnyList *headers, - TnyFolder *dst_folder); - /* * This function checks whether a TnyFolderStore is a pop account */ @@ -531,7 +527,7 @@ modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win) if (prev_row_reference != NULL) gtk_tree_row_reference_free (prev_row_reference); if (prev_path != NULL) - gtk_tree_path_free (prev_path); + gtk_tree_path_free (prev_path); } /* Update toolbar dimming state */ @@ -653,7 +649,6 @@ modest_ui_actions_on_accounts (GtkAction *action, } 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); @@ -661,18 +656,6 @@ modest_ui_actions_on_accounts (GtkAction *action, } } -#ifdef MODEST_PLATFORM_MAEMO -static void -on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data) -{ - /* Save any changes. */ - modest_connection_specific_smtp_window_save_server_accounts ( - MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window)); - gtk_widget_destroy (GTK_WIDGET (window)); -} -#endif - - void modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win) { @@ -688,14 +671,10 @@ modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win) MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), modest_runtime_get_account_mgr()); - /* Show the window: */ - gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win)); - gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE); + /* Show the window: */ + modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), + GTK_WINDOW (specific_window)); gtk_widget_show (specific_window); - - /* Save changes when the window is hidden: */ - g_signal_connect (specific_window, "hide", - G_CALLBACK (on_smtp_servers_window_hide), win); #endif /* MODEST_PLATFORM_MAEMO */ } @@ -718,6 +697,13 @@ modest_ui_actions_compose_msg(ModestWindow *win, ModestWindow *msg_win = NULL; ModestAccountMgr *mgr = modest_runtime_get_account_mgr(); ModestTnyAccountStore *store = modest_runtime_get_account_store(); + GnomeVFSFileSize total_size, allowed_size; + + /* we check for low-mem; in that case, show a warning, and don't allow + * composing a message with attachments + */ + if (attachments && modest_platform_check_memory_low (win, TRUE)) + goto cleanup; account_name = modest_account_mgr_get_default_account(mgr); if (!account_name) { @@ -747,7 +733,7 @@ modest_ui_actions_compose_msg(ModestWindow *win, body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup(""); } - msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL); + msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL); if (!msg) { g_printerr ("modest: failed to create new msg\n"); goto cleanup; @@ -755,10 +741,22 @@ modest_ui_actions_compose_msg(ModestWindow *win, /* Create and register edit window */ /* This is destroyed by TODO. */ + total_size = 0; + allowed_size = MODEST_MAX_ATTACHMENT_SIZE; msg_win = modest_msg_edit_window_new (msg, account_name, FALSE); while (attachments) { - modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win, - attachments->data); + total_size += + modest_msg_edit_window_attach_file_one( + (ModestMsgEditWindow *)msg_win, + attachments->data, allowed_size); + + if (total_size > allowed_size) { + g_warning ("%s: total size: %u", + __FUNCTION__, (unsigned int)total_size); + break; + } + allowed_size -= total_size; + attachments = g_slist_next(attachments); } modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win); @@ -771,10 +769,14 @@ cleanup: g_free (signature); g_free (body); g_free (account_name); - if (account) g_object_unref (G_OBJECT(account)); - if (folder) g_object_unref (G_OBJECT(folder)); - if (msg_win) g_object_unref (G_OBJECT(msg_win)); - if (msg) g_object_unref (G_OBJECT(msg)); + if (account) + g_object_unref (G_OBJECT(account)); + if (folder) + g_object_unref (G_OBJECT(folder)); + if (msg_win) + g_object_unref (G_OBJECT(msg_win)); + if (msg) + g_object_unref (G_OBJECT(msg)); } void @@ -799,6 +801,18 @@ modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op, /* If there is no message or the operation was not successful */ status = modest_mail_operation_get_status (mail_op); if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) { + const GError *error; + + /* If it's a memory low issue, then show a banner */ + error = modest_mail_operation_get_error (mail_op); + if (error && error->domain == MODEST_MAIL_OPERATION_ERROR && + error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) { + GObject *source = modest_mail_operation_get_source (mail_op); + modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL, + dgettext("ke-recv","memr_ib_operation_disabled"), + TRUE); + g_object_unref (source); + } /* Remove the header from the preregistered uids */ modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), @@ -831,7 +845,8 @@ open_msg_banner_idle (gpointer userdata) gdk_threads_enter (); banner_info->idle_handler = 0; banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message); - g_object_ref (banner_info->banner); + if (banner_info) + g_object_ref (banner_info->banner); gdk_threads_leave (); @@ -886,14 +901,16 @@ open_msg_cb (ModestMailOperation *mail_op, char *msg_id; account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account( TNY_ACCOUNT(traccount))); - send_queue = modest_runtime_get_send_queue(traccount); - msg_id = modest_tny_send_queue_get_msg_id (header); - status = modest_tny_send_queue_get_msg_status(send_queue, msg_id); - /* Only open messages in outbox with the editor if they are in Failed state */ - if (status == MODEST_TNY_SEND_QUEUE_FAILED) { - open_in_editor = TRUE; + send_queue = modest_runtime_get_send_queue(traccount, TRUE); + if (TNY_IS_SEND_QUEUE (send_queue)) { + msg_id = modest_tny_send_queue_get_msg_id (header); + status = modest_tny_send_queue_get_msg_status(send_queue, msg_id); + /* Only open messages in outbox with the editor if they are in Failed state */ + if (status == MODEST_TNY_SEND_QUEUE_FAILED) { + open_in_editor = TRUE; + } + g_free(msg_id); } - g_free(msg_id); g_object_unref(traccount); } else { g_warning("Cannot get transport account for message in outbox!!"); @@ -927,17 +944,19 @@ open_msg_cb (ModestMailOperation *mail_op, if (from_header) { GSList *accounts = modest_account_mgr_account_names (mgr, TRUE); GSList *node = NULL; + for (node = accounts; node != NULL; node = g_slist_next (node)) { gchar *from = modest_account_mgr_get_from_string (mgr, node->data); - + if (from && (strcmp (from_header, from) == 0)) { g_free (account); account = g_strdup (node->data); g_free (from); break; - } + } g_free (from); - } + } + g_free (from_header); g_slist_foreach (accounts, (GFunc) g_free, NULL); g_slist_free (accounts); @@ -1014,6 +1033,9 @@ modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op, modest_platform_information_banner ((GtkWidget *) win, NULL, dgettext("ke-recv", "cerm_device_memory_full")); + } else if (error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) { + modest_platform_information_banner ((GtkWidget *) win, + NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found")); } else if (user_data) { modest_platform_information_banner ((GtkWidget *) win, NULL, user_data); @@ -1337,7 +1359,7 @@ open_msgs_from_headers (TnyList *headers, ModestWindow *win) } } } - + /* Register the headers before actually creating the windows: */ iter_not_opened = tny_list_create_iterator (not_opened_headers); while (!tny_iterator_is_done (iter_not_opened)) { @@ -1381,6 +1403,12 @@ void modest_ui_actions_on_open (GtkAction *action, ModestWindow *win) { TnyList *headers; + + /* we check for low-mem; in that case, show a warning, and don't allow + * opening + */ + if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE)) + return; /* Get headers */ headers = get_selected_headers (win); @@ -1393,6 +1421,26 @@ modest_ui_actions_on_open (GtkAction *action, ModestWindow *win) g_object_unref(headers); } +static ReplyForwardHelper* +create_reply_forward_helper (ReplyForwardAction action, + ModestWindow *win, + guint reply_forward_type, + TnyHeader *header) +{ + ReplyForwardHelper *rf_helper = NULL; + const gchar *active_acc = modest_window_get_active_account (win); + + rf_helper = g_slice_new0 (ReplyForwardHelper); + rf_helper->reply_forward_type = reply_forward_type; + rf_helper->action = action; + rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL; + rf_helper->header = (header) ? g_object_ref (header) : NULL; + rf_helper->account_name = (active_acc) ? + g_strdup (active_acc) : + modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); + + return rf_helper; +} static void free_reply_forward_helper (gpointer data) @@ -1401,6 +1449,8 @@ free_reply_forward_helper (gpointer data) helper = (ReplyForwardHelper *) data; g_free (helper->account_name); + if (helper->header) + g_object_unref (helper->header); g_slice_free (ReplyForwardHelper, helper); } @@ -1412,7 +1462,7 @@ reply_forward_cb (ModestMailOperation *mail_op, GError *err, gpointer user_data) { - TnyMsg *new_msg; + TnyMsg *new_msg = NULL; ReplyForwardHelper *rf_helper; ModestWindow *msg_win = NULL; ModestEditType edit_type; @@ -1425,11 +1475,9 @@ reply_forward_cb (ModestMailOperation *mail_op, /* If there was any error. The mail operation could be NULL, this means that we already have the message downloaded and that we didn't do a mail operation to retrieve it */ - if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) - return; - - g_return_if_fail (user_data != NULL); rf_helper = (ReplyForwardHelper *) user_data; + if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) + goto cleanup; from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), rf_helper->account_name); @@ -1465,10 +1513,11 @@ reply_forward_cb (ModestMailOperation *mail_op, return; } + g_free (from); g_free (signature); if (!new_msg) { - g_printerr ("modest: failed to create message\n"); + g_warning ("%s: failed to create message\n", __FUNCTION__); goto cleanup; } @@ -1476,7 +1525,7 @@ reply_forward_cb (ModestMailOperation *mail_op, rf_helper->account_name, TNY_ACCOUNT_TYPE_STORE); if (!account) { - g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name); + g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name); goto cleanup; } @@ -1502,7 +1551,6 @@ cleanup: g_object_unref (G_OBJECT (new_msg)); if (account) g_object_unref (G_OBJECT (account)); -/* g_object_unref (msg); */ free_reply_forward_helper (rf_helper); } @@ -1559,20 +1607,50 @@ connect_to_get_msg (ModestWindow *win, return modest_platform_connect_and_wait((GtkWindow *) win, account); } +static void +reply_forward_performer (gboolean canceled, + GError *err, + GtkWindow *parent_window, + TnyAccount *account, + gpointer user_data) +{ + ReplyForwardHelper *rf_helper = NULL; + ModestMailOperation *mail_op; + + rf_helper = (ReplyForwardHelper *) user_data; + + if (canceled || err) { + free_reply_forward_helper (rf_helper); + return; + } + + /* Retrieve the message */ + mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window), + modest_ui_actions_disk_operations_error_handler, + NULL, NULL); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper); + + /* Frees */ + g_object_unref(mail_op); +} + /* * Common code for the reply and forward actions */ static void reply_forward (ReplyForwardAction action, ModestWindow *win) { - ModestMailOperation *mail_op = NULL; - TnyList *header_list = NULL; ReplyForwardHelper *rf_helper = NULL; guint reply_forward_type; - gboolean continue_download = TRUE; - gboolean do_retrieve = TRUE; g_return_if_fail (MODEST_IS_WINDOW(win)); + + /* we check for low-mem; in that case, show a warning, and don't allow + * reply/forward (because it could potentially require a lot of memory */ + if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE)) + return; + /* we need an account when editing */ if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) { @@ -1580,113 +1658,115 @@ reply_forward (ReplyForwardAction action, ModestWindow *win) return; } - header_list = get_selected_headers (win); - if (!header_list) - return; - - reply_forward_type = + reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (), - (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE, + (action == ACTION_FORWARD) ? + MODEST_CONF_FORWARD_TYPE : + MODEST_CONF_REPLY_TYPE, NULL); - /* check if we need to download msg before asking about it */ - do_retrieve = (action == ACTION_FORWARD) || - (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE); - - if (do_retrieve){ - gint num_of_unc_msgs; - - /* check that the messages have been previously downloaded */ - num_of_unc_msgs = header_list_count_uncached_msgs(header_list); - /* If there are any uncached message ask the user - * whether he/she wants to download them. */ - if (num_of_unc_msgs) { - TnyAccount *account = get_account_from_header_list (header_list); - if (account) { - continue_download = connect_to_get_msg (win, num_of_unc_msgs, account); - g_object_unref (account); - } - } - } - - if (!continue_download) { - g_object_unref (header_list); - return; - } - - /* We assume that we can only select messages of the - same folder and that we reply all of them from the - same account. In fact the interface currently only - allows single selection */ - - /* Fill helpers */ - rf_helper = g_slice_new0 (ReplyForwardHelper); - rf_helper->reply_forward_type = reply_forward_type; - rf_helper->action = action; - rf_helper->account_name = g_strdup (modest_window_get_active_account (win)); - - if ((win != NULL) && (MODEST_IS_WINDOW (win))) - rf_helper->parent_window = GTK_WIDGET (win); - if (!rf_helper->account_name) - rf_helper->account_name = - modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); - - if (MODEST_IS_MSG_VIEW_WINDOW(win)) { - TnyMsg *msg; - TnyHeader *header; + if (MODEST_IS_MSG_VIEW_WINDOW (win)) { + TnyMsg *msg = NULL; + TnyHeader *header = NULL; /* Get header and message. Do not free them here, the reply_forward_cb must do it */ msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win)); - header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win)); - if (!msg || !header) { - if (msg) - g_object_unref (msg); - g_printerr ("modest: no message found\n"); - return; - } else { + header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win)); + + if (msg && header) { + /* Create helper */ + rf_helper = create_reply_forward_helper (action, win, + reply_forward_type, header); reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper); + } else { + g_warning("%s: no message or header found in viewer\n", __FUNCTION__); } - if (header) + + if (msg) + g_object_unref (msg); + if (header) g_object_unref (header); } else { - TnyHeader *header; + TnyHeader *header = NULL; TnyIterator *iter; + gboolean do_retrieve = TRUE; + TnyList *header_list = NULL; + + header_list = get_selected_headers (win); + if (!header_list) + return; + if (tny_list_get_length (header_list) == 0) { + g_object_unref (header_list); + return; + } /* Only reply/forward to one message */ iter = tny_list_create_iterator (header_list); header = TNY_HEADER (tny_iterator_get_current (iter)); g_object_unref (iter); - if (header) { - /* Retrieve messages */ - if (do_retrieve) { - mail_op = - modest_mail_operation_new_with_error_handling (G_OBJECT(win), - modest_ui_actions_disk_operations_error_handler, - NULL, NULL); - modest_mail_operation_queue_add ( - modest_runtime_get_mail_operation_queue (), mail_op); - - modest_mail_operation_get_msg (mail_op, - header, - reply_forward_cb, - rf_helper); - /* Clean */ - g_object_unref(mail_op); - } else { - /* we put a ref here to prevent double unref as the reply - * forward callback unrefs the header at its end */ - reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper); - } + /* Retrieve messages */ + do_retrieve = (action == ACTION_FORWARD) || + (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE); + if (do_retrieve) { + TnyAccount *account = NULL; + TnyFolder *folder = NULL; + gdouble download = TRUE; + guint uncached_msgs = 0; - g_object_unref (header); + folder = tny_header_get_folder (header); + if (!folder) + goto do_retrieve_frees; + account = tny_folder_get_account (folder); + if (!account) + goto do_retrieve_frees; + + uncached_msgs = header_list_count_uncached_msgs (header_list); + + if (uncached_msgs > 0) { + /* Allways download if we are online. */ + if (!tny_device_is_online (modest_runtime_get_device ())) { + gint response; + + /* If ask for user permission to download the messages */ + response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win), + ngettext("mcen_nc_get_msg", + "mcen_nc_get_msgs", + uncached_msgs)); + + /* End if the user does not want to continue */ + if (response == GTK_RESPONSE_CANCEL) + download = FALSE; + } + } + + if (download) { + /* Create helper */ + rf_helper = create_reply_forward_helper (action, win, + reply_forward_type, header); + if (uncached_msgs > 0) { + modest_platform_connect_and_perform (GTK_WINDOW (win), + TRUE, account, + reply_forward_performer, + rf_helper); + } else { + reply_forward_performer (FALSE, NULL, GTK_WINDOW (win), + account, rf_helper); + } + } + do_retrieve_frees: + if (account) + g_object_unref (account); + if (folder) + g_object_unref (folder); + } else { + reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper); } - + /* Frees */ + g_object_unref (header_list); + g_object_unref (header); } - - /* Free */ - g_object_unref (header_list); } void @@ -1963,7 +2043,7 @@ modest_ui_actions_do_cancel_send (const gchar *account_name, } /* Get send queue*/ - send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account)); + send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE)); if (!TNY_IS_SEND_QUEUE(send_queue)) { g_set_error (&error, MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, @@ -2155,6 +2235,7 @@ modest_ui_actions_on_header_activated (ModestHeaderView *header_view, ModestMainWindow *main_window) { TnyList *headers; + GtkWidget *open_widget; g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); @@ -2166,9 +2247,17 @@ modest_ui_actions_on_header_activated (ModestHeaderView *header_view, return; } + /* we check for low-mem; in that case, show a warning, and don't allow + * activating headers + */ + if (modest_platform_check_memory_low (MODEST_WINDOW(main_window), TRUE)) + return; + + modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window)); + open_widget = modest_window_get_action_widget (MODEST_WINDOW (main_window), "/MenuBar/EmailMenu/EmailOpenMenu"); + if (!GTK_WIDGET_IS_SENSITIVE (open_widget)) + return; -/* headers = tny_simple_list_new (); */ -/* tny_list_prepend (headers, G_OBJECT (header)); */ headers = modest_header_view_get_selected_headers (header_view); open_msgs_from_headers (headers, MODEST_WINDOW (main_window)); @@ -2214,10 +2303,22 @@ folder_refreshed_cb (ModestMailOperation *mail_op, { ModestMainWindow *win = NULL; GtkWidget *header_view; + const GError *error; g_return_if_fail (TNY_IS_FOLDER (folder)); win = MODEST_MAIN_WINDOW (user_data); + + /* Check if the operation failed due to memory low conditions */ + error = modest_mail_operation_get_error (mail_op); + if (error && error->domain == MODEST_MAIL_OPERATION_ERROR && + error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) { + modest_platform_run_information_dialog (GTK_WINDOW (win), + dgettext("ke-recv","memr_ib_operation_disabled"), + TRUE); + return; + } + header_view = modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW); @@ -2392,7 +2493,13 @@ modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* l void modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part, ModestWindow *win) -{ +{ + /* we check for low-mem; in that case, show a warning, and don't allow + * viewing attachments + */ + if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE)) + return; + modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part); } @@ -2466,6 +2573,35 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi return FALSE; } + /* + * djcb: if we're in low-memory state, we only allow for + * saving messages smaller than + * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this + * should still allow for sending anything critical... + */ + if (expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) { + + if (modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE)) { + modest_msg_edit_window_free_msg_data (edit_window, data); + return FALSE; + } + } + + /* + * djcb: we also make sure that the attachments are smaller than the max size + * this is for the case where we'd try to forward a message with attachments + * bigger than our max allowed size, or sending an message from drafts which + * somehow got past our checks when attaching. + */ + if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) { + modest_platform_run_information_dialog ( + GTK_WINDOW(edit_window), + dgettext("ke-recv","memr_ib_operation_disabled"), + TRUE); + modest_msg_edit_window_free_msg_data (edit_window, data); + return FALSE; + } + account_name = g_strdup (data->account_name); account_mgr = modest_runtime_get_account_mgr(); if (!account_name) @@ -2608,6 +2744,34 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) return FALSE; } + + /* + * djcb: if we're in low-memory state, we only allow for sending messages + * smaller than MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) + * this should still allow for sending anything critical... + */ + if (expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) { + if (modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE)) { + modest_msg_edit_window_free_msg_data (edit_window, data); + return FALSE; + } + } + + /* + * djcb: we also make sure that the attachments are smaller than the max size + * this is for the case where we'd try to forward a message with attachments + * bigger than our max allowed size, or sending an message from drafts which + * somehow got past our checks when attaching. + */ + if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) { + modest_platform_run_information_dialog ( + GTK_WINDOW(edit_window), + dgettext("ke-recv","memr_ib_operation_disabled"), + TRUE); + modest_msg_edit_window_free_msg_data (edit_window, data); + return FALSE; + } + ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr(); gchar *account_name = g_strdup (data->account_name); if (!account_name) @@ -2641,7 +2805,7 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name); /* Create the mail operation */ - ModestMailOperation *mail_operation = modest_mail_operation_new (NULL); + ModestMailOperation *mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation); modest_mail_operation_send_new_mail (mail_operation, @@ -2808,6 +2972,10 @@ modest_ui_actions_on_insert_image (GtkAction *action, g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window)); g_return_if_fail (GTK_IS_ACTION (action)); + + if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE)) + return; + if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT) return; @@ -2821,6 +2989,9 @@ modest_ui_actions_on_attach_file (GtkAction *action, g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window)); g_return_if_fail (GTK_IS_ACTION (action)); + if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE)) + return; + modest_msg_edit_window_offer_attach_file (window); } @@ -2988,6 +3159,11 @@ modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op, case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS: message = _CS("ckdg_ib_folder_already_exists"); break; + case TNY_SERVICE_ERROR_STATE: + /* This means that the folder is already in use (a + message is opened for example */ + message = _("emev_ni_internal_error"); + break; default: message = _("emev_ib_ui_imap_unable_to_rename"); } @@ -3009,6 +3185,11 @@ on_rename_folder_cb (ModestMailOperation *mail_op, { ModestFolderView *folder_view; + /* If the window was closed when renaming a folder this could + happen */ + if (!MODEST_IS_FOLDER_VIEW (user_data)) + return; + folder_view = MODEST_FOLDER_VIEW (user_data); /* Note that if the rename fails new_folder will be NULL */ if (new_folder) { @@ -3016,6 +3197,7 @@ on_rename_folder_cb (ModestMailOperation *mail_op, } else { modest_folder_view_select_first_inbox_or_local (folder_view); } + gtk_widget_grab_focus (GTK_WIDGET (folder_view)); } static void @@ -3248,6 +3430,30 @@ modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainW } +typedef struct _PasswordDialogFields { + GtkWidget *username; + GtkWidget *password; + GtkWidget *dialog; +} PasswordDialogFields; + +static void +password_dialog_check_field (GtkEditable *editable, + PasswordDialogFields *fields) +{ + const gchar *value; + gboolean any_value_empty = FALSE; + + value = gtk_entry_get_text (GTK_ENTRY (fields->username)); + if ((value == NULL) || value[0] == '\0') { + any_value_empty = TRUE; + } + value = gtk_entry_get_text (GTK_ENTRY (fields->password)); + if ((value == NULL) || value[0] == '\0') { + any_value_empty = TRUE; + } + gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty); +} + void modest_ui_actions_on_password_requested (TnyAccountStore *account_store, const gchar* server_account_name, @@ -3259,6 +3465,7 @@ modest_ui_actions_on_password_requested (TnyAccountStore *account_store, { g_return_if_fail(server_account_name); gboolean completed = FALSE; + PasswordDialogFields *fields = NULL; /* Initalize output parameters: */ if (cancel) @@ -3319,11 +3526,16 @@ modest_ui_actions_on_password_requested (TnyAccountStore *account_store, gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username); /* Dim this if a connection has ever succeeded with this username, * as per the UI spec: */ - const gboolean username_known = - modest_account_mgr_get_server_account_username_has_succeeded( - modest_runtime_get_account_mgr(), server_account_name); - gtk_widget_set_sensitive (entry_username, !username_known); - + /* const gboolean username_known = */ + /* modest_account_mgr_get_server_account_username_has_succeeded( */ + /* modest_runtime_get_account_mgr(), server_account_name); */ + /* gtk_widget_set_sensitive (entry_username, !username_known); */ + + /* We drop the username sensitive code and disallow changing it here + * as tinymail does not support really changing the username in the callback + */ + gtk_widget_set_sensitive (entry_username, FALSE); + #ifdef MODEST_PLATFORM_MAEMO /* Auto-capitalization is the default, so let's turn it off: */ hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL); @@ -3375,6 +3587,15 @@ modest_ui_actions_on_password_requested (TnyAccountStore *account_store, TRUE, FALSE, 0); */ + fields = g_slice_new0 (PasswordDialogFields); + fields->username = entry_username; + fields->password = entry_password; + fields->dialog = dialog; + + g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields); + g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields); + password_dialog_check_field (NULL, fields); + gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox)); while (!completed) { @@ -3438,6 +3659,7 @@ modest_ui_actions_on_password_requested (TnyAccountStore *account_store, */ gtk_widget_destroy (dialog); + g_slice_free (PasswordDialogFields, fields); /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */ } @@ -3617,8 +3839,10 @@ paste_as_attachment_free (gpointer data) { PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data; - gtk_widget_destroy (helper->banner); - g_object_unref (helper->banner); + if (helper->banner) { + gtk_widget_destroy (helper->banner); + g_object_unref (helper->banner); + } g_free (helper); } @@ -3672,7 +3896,6 @@ modest_ui_actions_on_paste (GtkAction *action, mail_op = modest_mail_operation_new (G_OBJECT (window)); if (helper->banner != NULL) { g_object_ref (G_OBJECT (helper->banner)); - gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE); gtk_widget_show (GTK_WIDGET (helper->banner)); } @@ -4405,40 +4628,6 @@ create_move_to_dialog (GtkWindow *win, return dialog; } -/* - * Returns TRUE if at least one of the headers of the list belongs to - * a message that has been fully retrieved. - */ -#if 0 /* no longer in use. delete in 2007.10 */ -static gboolean -has_retrieved_msgs (TnyList *list) -{ - TnyIterator *iter; - gboolean found = FALSE; - - iter = tny_list_create_iterator (list); - while (!tny_iterator_is_done (iter) && !found) { - TnyHeader *header; - TnyHeaderFlags flags = 0; - - header = TNY_HEADER (tny_iterator_get_current (iter)); - if (header) { - flags = tny_header_get_flags (header); - if (flags & TNY_HEADER_FLAG_CACHED) -/* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */ - found = TRUE; - - g_object_unref (header); - } - - if (!found) - tny_iterator_next (iter); - } - g_object_unref (iter); - - return found; -} -#endif /* 0 */ /* @@ -4503,6 +4692,21 @@ modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win, } static void +move_to_helper_destroyer (gpointer user_data) +{ + MoveToHelper *helper = (MoveToHelper *) user_data; + + /* Close the "Pasting" information banner */ + if (helper->banner) { + gtk_widget_destroy (GTK_WIDGET (helper->banner)); + g_object_unref (helper->banner); + } + if (helper->reference != NULL) + gtk_tree_row_reference_free (helper->reference); + g_free (helper); +} + +static void move_to_cb (ModestMailOperation *mail_op, gpointer user_data) { @@ -4540,13 +4744,8 @@ move_to_cb (ModestMailOperation *mail_op, } g_object_unref (object); } - - /* Close the "Pasting" information banner */ - gtk_widget_destroy (GTK_WIDGET(helper->banner)); - g_object_unref (helper->banner); - if (helper->reference != NULL) - gtk_tree_row_reference_free (helper->reference); - g_free (helper); + /* Destroy the helper */ + move_to_helper_destroyer (helper); } static void @@ -4738,7 +4937,7 @@ modest_ui_actions_on_main_window_remove_attachments (GtkAction *action, modest_ui_actions_disk_operations_error_handler, NULL, NULL); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win); + modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win); g_object_unref (mail_op); } @@ -4833,7 +5032,7 @@ xfer_messages_error_handler (ModestMailOperation *mail_op, gpointer user_data) { ModestWindow *main_window = NULL; - + /* Disable next automatic folder selection */ main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (), FALSE); /* don't create */ @@ -4845,8 +5044,14 @@ xfer_messages_error_handler (ModestMailOperation *mail_op, if (win) g_object_unref (win); } + move_to_helper_destroyer (user_data); } +typedef struct { + TnyFolderStore *dst_folder; + TnyList *headers; +} XferMsgsHelper; + /** * Utility function that transfer messages from both the main window * and the msg view window when using the "Move to" dialog @@ -4858,12 +5063,15 @@ xfer_messages_performer (gboolean canceled, TnyAccount *account, gpointer user_data) { - TnyFolderStore *dst_folder = TNY_FOLDER_STORE (user_data); ModestWindow *win = MODEST_WINDOW (parent_window); - TnyList *headers = NULL; TnyAccount *dst_account = NULL; const gchar *proto_str = NULL; gboolean dst_is_pop = FALSE; + XferMsgsHelper *helper; + MoveToHelper *movehelper; + ModestMailOperation *mail_op; + + helper = (XferMsgsHelper *) user_data; if (canceled) goto end; @@ -4880,7 +5088,7 @@ xfer_messages_performer (gboolean canceled, goto end; } - dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder)); + dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder)); proto_str = tny_account_get_proto (dst_account); /* tinymail will return NULL for local folders it seems */ @@ -4890,58 +5098,49 @@ xfer_messages_performer (gboolean canceled, g_object_unref (dst_account); - /* Get selected headers */ - headers = get_selected_headers (MODEST_WINDOW (win)); - if (!headers) { - g_warning ("%s: no headers selected", __FUNCTION__); - return; - } - - if (dst_is_pop) { modest_platform_information_banner (GTK_WIDGET (win), NULL, ngettext("mail_in_ui_folder_move_target_error", "mail_in_ui_folder_move_targets_error", - tny_list_get_length (headers))); - g_object_unref (headers); - return; + tny_list_get_length (helper->headers))); + goto end; } - MoveToHelper *helper = g_new0 (MoveToHelper, 1); - helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL, - _CS("ckct_nw_pasting")); - if (helper->banner != NULL) { - g_object_ref (helper->banner); - gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE); - gtk_widget_show (GTK_WIDGET(helper->banner)); + movehelper = g_new0 (MoveToHelper, 1); + movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL, + _CS("ckct_nw_pasting")); + if (movehelper->banner != NULL) { + g_object_ref (movehelper->banner); + gtk_widget_show (GTK_WIDGET (movehelper->banner)); } if (MODEST_IS_MAIN_WINDOW (win)) { GtkWidget *header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win), MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW); - helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view)); + movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view)); } - ModestMailOperation *mail_op = - modest_mail_operation_new_with_error_handling (G_OBJECT(win), - xfer_messages_error_handler, - NULL, NULL); + /* Perform the mail operation */ + mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win), + xfer_messages_error_handler, + movehelper, NULL); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); modest_mail_operation_xfer_msgs (mail_op, - headers, - TNY_FOLDER (dst_folder), + helper->headers, + TNY_FOLDER (helper->dst_folder), TRUE, msgs_move_to_cb, - helper); + movehelper); g_object_unref (G_OBJECT (mail_op)); - g_object_unref (headers); end: - g_object_unref (dst_folder); + g_object_unref (helper->dst_folder); + g_object_unref (helper->headers); + g_slice_free (XferMsgsHelper, helper); } typedef struct { @@ -4971,7 +5170,6 @@ on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window, _CS("ckct_nw_pasting")); if (helper->banner != NULL) { g_object_ref (helper->banner); - gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE); gtk_widget_show (GTK_WIDGET(helper->banner)); } /* Clean folder on header view before moving it */ @@ -5085,8 +5283,8 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, headers = modest_header_view_get_selected_headers(header_view); /* Transfer the messages */ - transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder), - headers, TNY_FOLDER (dst_folder)); + modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder), + headers, TNY_FOLDER (dst_folder)); g_object_unref (headers); } @@ -5096,14 +5294,15 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, } -static void -transfer_messages_helper (GtkWindow *win, - TnyFolder *src_folder, - TnyList *headers, - TnyFolder *dst_folder) +void +modest_ui_actions_transfer_messages_helper (GtkWindow *win, + TnyFolder *src_folder, + TnyList *headers, + TnyFolder *dst_folder) { gboolean need_connection = TRUE; gboolean do_xfer = TRUE; + XferMsgsHelper *helper; modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder), headers, TNY_FOLDER (dst_folder), @@ -5114,11 +5313,16 @@ transfer_messages_helper (GtkWindow *win, if (!do_xfer) return; + /* Create the helper */ + helper = g_slice_new (XferMsgsHelper); + helper->dst_folder = g_object_ref (dst_folder); + helper->headers = g_object_ref (headers); + if (need_connection) { DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo); connect_info->callback = xfer_messages_performer; connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder)); - connect_info->data = g_object_ref (dst_folder); + connect_info->data = helper; modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE, TNY_FOLDER_STORE (src_folder), @@ -5126,8 +5330,7 @@ transfer_messages_helper (GtkWindow *win, } else { TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder)); xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win), - src_account, - g_object_ref (dst_folder)); + src_account, helper); g_object_unref (src_account); } } @@ -5154,8 +5357,8 @@ modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, tny_list_append (headers, G_OBJECT (header)); /* Transfer the messages */ - transfer_messages_helper (GTK_WINDOW (win), src_folder, headers, - TNY_FOLDER (dst_folder)); + modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers, + TNY_FOLDER (dst_folder)); /* Frees */ g_object_unref (header); @@ -5279,6 +5482,10 @@ modest_ui_actions_save_attachments (GtkAction *action, ModestWindow *window) { if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + + if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE)) + return; + modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL); } else { /* not supported window for this action */ @@ -5322,15 +5529,53 @@ modest_ui_actions_on_help (GtkAction *action, { const gchar *help_id; - g_return_if_fail (action); g_return_if_fail (win && GTK_IS_WINDOW(win)); help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win); - - if (help_id) - modest_platform_show_help (GTK_WINDOW (win), help_id); + + if (help_id) + modest_platform_show_help (GTK_WINDOW (win), help_id); +} + +void +modest_ui_actions_on_csm_help (GtkAction *action, + GtkWindow *win) +{ + const gchar* help_id = NULL; + GtkWidget *folder_view; + TnyFolderStore *folder_store; + + g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win)); + + /* Get selected folder */ + folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), + MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW); + folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); + + /* Switch help_id */ + if (folder_store && TNY_IS_FOLDER (folder_store)) + help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store)); + + if (folder_store) + g_object_unref (folder_store); + + if (help_id) + modest_platform_show_help (GTK_WINDOW (win), help_id); else - g_warning ("%s: no help for window %p", __FUNCTION__, win); + modest_ui_actions_on_help (action, win); +} + +static void +retrieve_contents_cb (ModestMailOperation *mail_op, + TnyHeader *header, + gboolean canceled, + TnyMsg *msg, + GError *err, + gpointer user_data) +{ + /* We only need this callback to show an error in case of + memory low condition */ + modest_ui_actions_msg_retrieval_check (mail_op, header, msg); } static void @@ -5357,7 +5602,7 @@ retrieve_msg_contents_performer (gboolean canceled, modest_ui_actions_disk_operations_error_handler, NULL, NULL); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL); + modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL); /* Frees */ g_object_unref (mail_op); @@ -5514,6 +5759,12 @@ modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window) { g_return_if_fail (MODEST_IS_WINDOW (window)); + /* we check for low-mem; in that case, show a warning, and don't allow + * searching + */ + if (modest_platform_check_memory_low (window, TRUE)) + return; + modest_platform_show_search_messages (GTK_WINDOW (window)); } @@ -5521,6 +5772,15 @@ void modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win) { g_return_if_fail (MODEST_IS_WINDOW (win)); + + + /* we check for low-mem; in that case, show a warning, and don't allow + * for the addressbook + */ + if (modest_platform_check_memory_low (win, TRUE)) + return; + + modest_platform_show_addressbook (GTK_WINDOW (win)); }