X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fmodest-ui-actions.c;h=96a8b2d11208a13b4fec7a23155f905d9ed32553;hb=a15fc8e70d5c5bdb119780511ad9410ecdd6b2b7;hp=b26c725eab6ac29d42acaabcaf5930449c0fa957;hpb=fcba9e7fe620d44b9b4cf3b53717b583cbf23d8b;p=modest diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index b26c725..96a8b2d 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -48,6 +48,7 @@ #ifdef MODEST_PLATFORM_MAEMO #include "maemo/modest-osso-state-saving.h" +#include "maemo/modest-maemo-utils.h" #endif /* MODEST_PLATFORM_MAEMO */ #include "widgets/modest-ui-constants.h" @@ -121,6 +122,9 @@ static void reply_forward_cb (ModestMailOperation *mail_op, static void reply_forward (ReplyForwardAction action, ModestWindow *win); +static void folder_refreshed_cb (ModestMailOperation *mail_op, + TnyFolder *folder, + gpointer user_data); static void _on_send_receive_progress_changed (ModestMailOperation *mail_op, ModestMailOperationState *state, @@ -250,12 +254,12 @@ headers_action_delete (TnyHeader *header, g_object_unref (G_OBJECT (mail_op)); /* refilter treemodel to hide marked-as-deleted rows */ - if (MODEST_IS_HEADER_VIEW (user_data)) - modest_header_view_refilter (MODEST_HEADER_VIEW (user_data)); +/* if (MODEST_IS_HEADER_VIEW (user_data)) */ +/* modest_header_view_refilter (MODEST_HEADER_VIEW (user_data)); */ } void -modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win) +modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win) { TnyList *header_list = NULL; TnyIterator *iter = NULL; @@ -326,9 +330,29 @@ modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win) if (response == GTK_RESPONSE_OK) { - ModestMainWindow *main_window; - ModestWindowMgr *mgr; - + ModestWindow *main_window = NULL; + ModestWindowMgr *mgr = NULL; + GtkTreeModel *model = NULL; + GtkTreeSelection *sel = NULL; + GList *sel_list = NULL, *tmp = NULL; + GtkTreeRowReference *row_reference = NULL; + GtkTreePath *next_path = NULL; + + /* Find last selected row */ + if (MODEST_IS_MAIN_WINDOW (win)) { + model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)); + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view)); + sel_list = gtk_tree_selection_get_selected_rows (sel, &model); + for (tmp=sel_list; tmp; tmp=tmp->next) { + if (tmp->next == NULL) { + next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data); + gtk_tree_path_next (next_path); + row_reference = gtk_tree_row_reference_new (model, next_path); + gtk_tree_path_free (next_path); + } + } + } + /* Remove each header. If it's a view window header_view == NULL */ do_headers_action (win, headers_action_delete, header_view); @@ -340,30 +364,63 @@ modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win) } else { modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (win)); } + + /* Get main window */ + mgr = modest_runtime_get_window_mgr (); + main_window = modest_window_mgr_get_main_window (mgr); } - - /* Refilter header view model, if main window still exists */ - mgr = modest_runtime_get_window_mgr (); - main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr)); - if (main_window) { - GtkWidget *widget; - - widget = modest_main_window_get_child_widget (main_window, - MODEST_WIDGET_TYPE_HEADER_VIEW); - modest_header_view_refilter (MODEST_HEADER_VIEW (widget)); + else { + /* Move cursor to next row */ + main_window = win; + + /* Select next row */ + if (gtk_tree_row_reference_valid (row_reference)) { + next_path = gtk_tree_row_reference_get_path (row_reference); + gtk_tree_selection_select_path (sel, next_path); + gtk_tree_path_free (next_path); + } + if (row_reference != NULL) + gtk_tree_row_reference_free (row_reference); } /* Update toolbar dimming state */ - modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win)); + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window)); + + /* Free */ + g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL); + g_list_free (sel_list); } - /* free */ + /* Free*/ g_free(message); g_free(desc); g_object_unref (header_list); } + + +/* delete either message or folder, based on where we are */ +void +modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win) +{ + g_return_if_fail (MODEST_IS_WINDOW(win)); + + /* Check first if the header view has the focus */ + if (MODEST_IS_MAIN_WINDOW (win)) { + GtkWidget *w; + w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), + MODEST_WIDGET_TYPE_FOLDER_VIEW); + if (gtk_widget_is_focus (w)) { + modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win)); + return; + } + } + modest_ui_actions_on_delete_message (action, win); +} + + + void modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win) { @@ -436,9 +493,7 @@ modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win) } else { /* Show the list of accounts: */ GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ()); - gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win)); - gtk_dialog_run (account_win); - gtk_widget_destroy (GTK_WIDGET(account_win)); + modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win); } #else GtkWidget *dialog, *label; @@ -953,8 +1008,10 @@ reply_forward_cb (ModestMailOperation *mail_op, ModestWindowMgr *mgr = NULL; gchar *signature = NULL; - /* If there was any error */ - if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) + /* 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); @@ -1046,7 +1103,8 @@ cleanup: * of them are currently downloaded */ static gboolean -download_uncached_messages (TnyList *header_list, GtkWindow *win) +download_uncached_messages (TnyList *header_list, GtkWindow *win, + gboolean reply_fwd) { TnyIterator *iter; gboolean retval; @@ -1073,11 +1131,15 @@ download_uncached_messages (TnyList *header_list, GtkWindow *win) retval = TRUE; if (uncached_messages > 0) { GtkResponseType response; - response = - modest_platform_run_confirmation_dialog (GTK_WINDOW (win), - ngettext("mcen_nc_get_msg", - "mcen_nc_get_msgs", - uncached_messages)); + if (reply_fwd) + response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win), + _("emev_nc_include_original")); + else + response = + modest_platform_run_confirmation_dialog (GTK_WINDOW (win), + ngettext("mcen_nc_get_msg", + "mcen_nc_get_msgs", + uncached_messages)); if (response == GTK_RESPONSE_CANCEL) retval = FALSE; else { @@ -1114,7 +1176,7 @@ reply_forward (ReplyForwardAction action, ModestWindow *win) return; /* Check that the messages have been previously downloaded */ - continue_download = download_uncached_messages (header_list, GTK_WINDOW (win)); + continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE); if (!continue_download) { g_object_unref (header_list); return; @@ -1339,6 +1401,76 @@ modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win) g_free (acc_name); } + +static void +modest_ui_actions_do_cancel_send (const gchar *account_name, + ModestWindow *win) +{ + TnyTransportAccount *transport_account; + TnySendQueue *send_queue = NULL; + GError *error = NULL; + + /* Get transport account */ + transport_account = + TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account + (modest_runtime_get_account_store(), + account_name, + TNY_ACCOUNT_TYPE_TRANSPORT)); + if (!transport_account) { + g_printerr ("modest: no transport account found for '%s'\n", account_name); + goto frees; + } + + /* Get send queue*/ + send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account)); + if (!TNY_IS_SEND_QUEUE(send_queue)) { + g_set_error (&error, MODEST_MAIL_OPERATION_ERROR, + MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, + "modest: could not find send queue for account\n"); + } else { + /* Keeep messages in outbox folder */ + tny_send_queue_cancel (send_queue, FALSE, &error); + } + + frees: + if (transport_account != NULL) + g_object_unref (G_OBJECT (transport_account)); +} + +static void +modest_ui_actions_cancel_send_all (ModestWindow *win) +{ + GSList *account_names, *iter; + + account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), + TRUE); + + iter = account_names; + while (iter) { + modest_ui_actions_do_cancel_send ((const char*) iter->data, win); + iter = g_slist_next (iter); + } + + modest_account_mgr_free_account_names (account_names); + account_names = NULL; +} + +void +modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win) + +{ + /* Check if accounts exist */ + gboolean accounts_exist = + modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE); + + /* If not, allow the user to create an account before trying to send/receive. */ + if (!accounts_exist) + modest_ui_actions_on_accounts (NULL, win); + + /* Cancel all sending operaitons */ + modest_ui_actions_cancel_send_all (win); +} + /* * Refreshes all accounts. This function will be used by automatic * updates @@ -1374,6 +1506,40 @@ modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win) /* If not, allow the user to create an account before trying to send/receive. */ if (!accounts_exist) modest_ui_actions_on_accounts (NULL, win); + + /* Refresh currently selected folder. Note that if we only + want to retrive the headers, then the refresh only will + invoke a poke_status over all folders, i.e., only the + total/unread count will be updated */ + if (MODEST_IS_MAIN_WINDOW (win)) { + GtkWidget *header_view, *folder_view; + TnyFolderStore *folder_store; + + /* Get folder and header view */ + folder_view = + modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), + MODEST_WIDGET_TYPE_FOLDER_VIEW); + + folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); + + if (folder_store && TNY_IS_FOLDER (folder_store)) { + header_view = + modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), + MODEST_WIDGET_TYPE_HEADER_VIEW); + + /* We do not need to set the contents style + because it hasn't changed. We also do not + need to save the widget status. Just force + a refresh */ + modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), + TNY_FOLDER (folder_store), + folder_refreshed_cb, + MODEST_MAIN_WINDOW (win)); + } + + if (folder_store) + g_object_unref (folder_store); + } /* Refresh the active account */ modest_ui_actions_do_send_receive (NULL, win); @@ -1484,7 +1650,7 @@ set_active_account_from_tny_account (TnyAccount *account, static void -folder_refreshed_cb (const GObject *obj, +folder_refreshed_cb (ModestMailOperation *mail_op, TnyFolder *folder, gpointer user_data) { @@ -1712,6 +1878,7 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi modest_mail_operation_save_to_drafts (mail_operation, transport_account, data->draft_msg, + edit_window, from, data->to, data->cc, @@ -1743,6 +1910,10 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) if (!modest_msg_edit_window_check_names (edit_window)) return; + /* Offer the connection dialog, if necessary: */ + if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window))) + return; + /* FIXME: Code added just for testing. The final version will use the send queue provided by tinymail and some classifier */ @@ -1980,6 +2151,26 @@ modest_ui_actions_on_remove_attachments (GtkAction *action, modest_msg_edit_window_remove_attachments (window, NULL); } +static void +modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op, + gpointer user_data) +{ + ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data); + + /* TODO: Note that folder creation might go wrong due to other + * failures such as when the parent folder is non-writable. We can + * query a GError* with modest_mail_operation_get_error(), but the + * the error code (from tinymail) does not give us a clue about what + * has gone wrong. We might use the error->message but it might come + * from camel and not be suitable to show to the user directly. */ + modest_platform_information_banner (GTK_WIDGET (window), NULL, + _CS("ckdg_ib_folder_already_exists")); + +/* modest_platform_information_banner (GTK_WIDGET (window), NULL, + modest_mail_operation_get_error (mail_op)->message);*/ +} + + void modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window) { @@ -2007,26 +2198,41 @@ modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_windo suggested_name, &folder_name); + g_free (suggested_name); + suggested_name = NULL; + if (result == GTK_RESPONSE_REJECT) { finished = TRUE; } else { ModestMailOperation *mail_op; TnyFolder *new_folder = NULL; - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, - G_OBJECT(main_window)); + mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO, + G_OBJECT(main_window), + modest_ui_actions_new_folder_error_handler, + main_window); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); new_folder = modest_mail_operation_create_folder (mail_op, parent_folder, (const gchar *) folder_name); if (new_folder) { + if (main_window) { + folder_view = modest_main_window_get_child_widget (main_window, + MODEST_WIDGET_TYPE_FOLDER_VIEW); + if (folder_view) + modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), + new_folder, TRUE); + } + g_object_unref (new_folder); finished = TRUE; } g_object_unref (mail_op); } - g_free (folder_name); + + suggested_name = folder_name; folder_name = NULL; } @@ -2108,6 +2314,9 @@ modest_ui_actions_on_rename_folder (GtkAction *action, mail_op); modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); + + modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), + TNY_FOLDER(folder), TRUE); modest_mail_operation_rename_folder (mail_op, TNY_FOLDER (folder), @@ -2397,6 +2606,7 @@ modest_ui_actions_on_cut (GtkAction *action, clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget)); gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE); + gtk_clipboard_set_can_store (clipboard, NULL, 0); } else if (MODEST_IS_HEADER_VIEW (focused_widget)) { modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget)); } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) { @@ -2418,11 +2628,13 @@ modest_ui_actions_on_copy (GtkAction *action, gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1); } else if (GTK_IS_EDITABLE (focused_widget)) { gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget)); + } else if (GTK_IS_HTML (focused_widget)) { + gtk_html_copy (GTK_HTML (focused_widget)); } else if (GTK_IS_TEXT_VIEW (focused_widget)) { GtkTextBuffer *buffer; buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget)); gtk_text_buffer_copy_clipboard (buffer, clipboard); - modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget)); + gtk_clipboard_set_can_store (clipboard, NULL, 0); } else if (MODEST_IS_HEADER_VIEW (focused_widget)) { TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget)); TnyIterator *iter = tny_list_create_iterator (header_list); @@ -2441,7 +2653,7 @@ modest_ui_actions_on_copy (GtkAction *action, /* Check that the messages have been previously downloaded */ gboolean continue_download = TRUE; if (ask) - continue_download = download_uncached_messages (header_list, GTK_WINDOW (window)); + continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE); if (continue_download) modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget)); g_object_unref (header_list); @@ -2849,16 +3061,12 @@ void modest_ui_actions_toggle_folders_view (GtkAction *action, ModestMainWindow *main_window) { - ModestConf *conf; - g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); - conf = modest_runtime_get_conf (); - - if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT) - modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE); - else + if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT); + else + modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE); } void @@ -2922,7 +3130,7 @@ modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window static GtkWidget* -create_move_to_dialog (ModestWindow *win, +create_move_to_dialog (GtkWindow *win, GtkWidget *folder_view, GtkWidget **tree_view) { @@ -2957,6 +3165,8 @@ create_move_to_dialog (ModestWindow *win, modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view), TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); + modest_folder_view_show_non_move_folders(MODEST_FOLDER_VIEW (*tree_view), FALSE); + gtk_container_add (GTK_CONTAINER (scroll), *tree_view); /* Add scroll to dialog */ @@ -3263,15 +3473,27 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, /* Get the folder view */ folder_view = modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_FOLDER_VIEW); + + TnyFolderStore *src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); + + /* Offer the connection dialog if necessary, if the source folder is in a networked account: */ + if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) { + if (src_folder) { + g_object_unref (src_folder); + } + + return; + } /* Get header view */ header_view = modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW); /* Create and run the dialog */ - dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view); + dialog = create_move_to_dialog (GTK_WINDOW(win), folder_view, &tree_view); modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view)); result = gtk_dialog_run (GTK_DIALOG(dialog)); + modest_folder_view_show_non_move_folders(MODEST_FOLDER_VIEW (tree_view), TRUE); g_object_ref (tree_view); /* We do this to save an indentation level ;-) */ @@ -3285,39 +3507,32 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, goto end; /* Offer the connection dialog if necessary: */ - if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), folder_store)) { + if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), folder_store)) { goto end; } /* Get folder or messages to transfer */ if (gtk_widget_is_focus (folder_view)) { - TnyFolderStore *src_folder; - src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); - - /* Offer the connection dialog if necessary: */ - if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) { - - /* Clean folder on header view before moving it */ - modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); - - if (TNY_IS_FOLDER (src_folder)) { - mail_op = - modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, - G_OBJECT(win), - modest_ui_actions_move_folder_error_handler, - NULL); - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + + /* Clean folder on header view before moving it */ + modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); - modest_mail_operation_xfer_folder (mail_op, - TNY_FOLDER (src_folder), - folder_store, - TRUE, NULL, NULL); - /* Unref mail operation */ - g_object_unref (G_OBJECT (mail_op)); - } + if (TNY_IS_FOLDER (src_folder)) { + mail_op = + modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, + G_OBJECT(win), + modest_ui_actions_move_folder_error_handler, + NULL); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - /* Frees */ - g_object_unref (G_OBJECT (src_folder)); + modest_mail_operation_xfer_folder (mail_op, + TNY_FOLDER (src_folder), + folder_store, + TRUE, NULL, NULL); + /* Unref mail operation */ + g_object_unref (G_OBJECT (mail_op)); + } else { + g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__); } } else { if (gtk_widget_is_focus (header_view)) { @@ -3356,7 +3571,10 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, } end: - if (folder_store != NULL) + if (src_folder) + g_object_unref (src_folder); + + if (folder_store) g_object_unref (folder_store); gtk_widget_destroy (dialog); @@ -3386,8 +3604,9 @@ modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, folder_view = NULL; /* Create and run the dialog */ - dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view); + dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view); result = gtk_dialog_run (GTK_DIALOG(dialog)); + modest_folder_view_show_non_move_folders(MODEST_FOLDER_VIEW (tree_view), TRUE); if (result == GTK_RESPONSE_ACCEPT) { TnyFolderStore *folder_store; @@ -3598,8 +3817,10 @@ modest_ui_actions_on_help (GtkAction *action, help_id = "applications_email_archive"; break; default: - help_id = NULL; + help_id = "applications_email_mainview"; } + } else { + help_id = "applications_email_mainview"; } g_object_unref (folder_store); } else {