* modest-folder-view.c: change sorting for remote folders: make Inbox be the first...
[modest] / src / modest-ui-actions.c
index b99cf71..be1d2a0 100644 (file)
@@ -121,6 +121,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,
@@ -255,7 +258,7 @@ headers_action_delete (TnyHeader *header,
 }
 
 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;
@@ -351,10 +354,10 @@ modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
                        widget = modest_main_window_get_child_widget (main_window,
                                                                      MODEST_WIDGET_TYPE_HEADER_VIEW);
                        modest_header_view_refilter (MODEST_HEADER_VIEW (widget));
-               }
 
-               /* Update toolbar dimming state */
-               modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
+                       /* Update toolbar dimming state */
+                       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
+               }
        }
 
        /* free */
@@ -364,6 +367,38 @@ modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
 }
 
 
+
+
+/* delete either message or folder, based on what has focus */
+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_HEADER_VIEW);
+               if (gtk_widget_is_focus (w)) {
+                       modest_ui_actions_on_delete_message (action, win);
+                       return;
+               }
+               
+               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;
+               }
+       }
+       g_warning ("BUG: delete toolbar button pressed with neither headerview nor folderview "
+                  "having focus");
+}
+
+
+
 void
 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
 {
@@ -645,8 +680,11 @@ open_msg_cb (ModestMailOperation *mail_op,
        /* Do nothing if there was any problem with the mail
           operation. The error will be shown by the error_handler of
           the mail operation */
-       if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
+       if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
+               printf ("DEBUG: %s: modest_ui_actions_msg_retrieval_check() failed.\n", 
+                       __FUNCTION__);
                return;
+       }
 
        parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
        folder = tny_header_get_folder (header);
@@ -739,6 +777,8 @@ modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
        GObject *win = modest_mail_operation_get_source (mail_op);
 
        error = modest_mail_operation_get_error (mail_op);
+       printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
        if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
 
                modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
@@ -798,9 +838,6 @@ _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
                                g_warning ("debug: header %p already registered, waiting for window",
                                           header);
                } else {
-                       /* register the header before actually creating the window */
-                       modest_window_mgr_register_header (mgr, header);
-                               
                        if (!(flags & TNY_HEADER_FLAG_CACHED))
                                tny_list_append (not_opened_headers, G_OBJECT (header));
                        /* Check if msg has already been retreived */
@@ -810,6 +847,47 @@ _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
                g_object_unref (header);
                tny_iterator_next (iter);
        }
+       g_object_unref (iter);
+       iter = NULL;
+       
+       /* If some messages would have to be downloaded, ask the user to 
+        * make a connection. It's generally easier to do this here (in the mainloop) 
+        * than later in a thread:
+        */
+       if (tny_list_get_length (not_opened_cached_headers) > 0) {
+               gboolean connected = modest_platform_connect_and_wait (GTK_WINDOW (win));
+               
+               /* Don't go further if a connection would be necessary but none is available: */
+               if (!connected) {
+                       g_object_unref (not_opened_headers);
+                       g_object_unref (not_opened_cached_headers);
+                       return;
+               }
+       }
+       
+       /* Register the headers before actually creating the windows: */
+       TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
+       while (!tny_iterator_is_done (iter_not_opened)) {
+               TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
+               modest_window_mgr_register_header (mgr, header);
+               g_object_unref (header);
+               
+               tny_iterator_next (iter_not_opened);
+       }
+       g_object_unref (iter_not_opened);
+       iter_not_opened = NULL;
+       
+       TnyIterator *iter_cached = tny_list_create_iterator (not_opened_cached_headers);
+       while (!tny_iterator_is_done (iter_cached)) {
+               TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_cached));
+               modest_window_mgr_register_header (mgr, header);
+               g_object_unref (header);
+               
+               tny_iterator_next (iter_cached);
+       }
+       g_object_unref (iter_cached);
+       iter_cached = NULL;
+       
        
        /* Open each uncached message */
        if (tny_list_get_length (not_opened_headers) > 0) {
@@ -1296,6 +1374,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
@@ -1331,6 +1479,38 @@ 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 (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));
+               }
+               g_object_unref (folder_store);
+       }
        
        /* Refresh the active account */
        modest_ui_actions_do_send_receive (NULL, win);
@@ -1441,7 +1621,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)
 {
@@ -1630,6 +1810,7 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi
        gchar *account_name, *from;
        ModestAccountMgr *account_mgr;
        gchar *info_text = NULL;
+       TnyMsg *new_draft = NULL;
 
        g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
        
@@ -1666,18 +1847,18 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi
        mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
 
-       modest_mail_operation_save_to_drafts (mail_operation,
-                                             transport_account,
-                                             data->draft_msg,
-                                             from,
-                                             data->to, 
-                                             data->cc, 
-                                             data->bcc,
-                                             data->subject, 
-                                             data->plain_body, 
-                                             data->html_body,
-                                             data->attachments,
-                                             data->priority_flags);
+       new_draft = modest_mail_operation_save_to_drafts (mail_operation,
+                                                         transport_account,
+                                                         data->draft_msg,
+                                                         from,
+                                                         data->to, 
+                                                         data->cc, 
+                                                         data->bcc,
+                                                         data->subject, 
+                                                         data->plain_body, 
+                                                         data->html_body,
+                                                         data->attachments,
+                                                         data->priority_flags);
        /* Frees */
        g_free (from);
        g_free (account_name);
@@ -1686,6 +1867,10 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi
 
        modest_msg_edit_window_free_msg_data (edit_window, data);
 
+       modest_msg_edit_window_set_draft (edit_window, new_draft);
+       if (new_draft != NULL)
+               g_object_unref (new_draft);
+
        info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
        modest_platform_information_banner (NULL, NULL, info_text);
        g_free (info_text);
@@ -1700,6 +1885,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 */
@@ -1937,6 +2126,25 @@ 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)
 {
@@ -1964,14 +2172,20 @@ 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,
@@ -1983,7 +2197,8 @@ modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_windo
                                }
                                g_object_unref (mail_op);
                        }
-                       g_free (folder_name);
+
+                       suggested_name = folder_name;
                        folder_name = NULL;
                }
 
@@ -2354,6 +2569,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)) {
@@ -2379,7 +2595,7 @@ modest_ui_actions_on_copy (GtkAction *action,
                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);
@@ -3220,6 +3436,17 @@ 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,
@@ -3242,39 +3469,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)) {
@@ -3313,7 +3533,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);