From: Murray Cumming Date: Wed, 4 Jul 2007 10:12:09 +0000 (+0000) Subject: 2007-07-04 Murray Cumming X-Git-Tag: git_migration_finished~2978 X-Git-Url: http://git.maemo.org/git/?p=modest;a=commitdiff_plain;h=2f51f213469dc0679fd33c205a6f6aa0c20481a9 2007-07-04 Murray Cumming * src/maemo/modest-msg-view-window.c: (modest_msg_view_window_select_next_message): * src/modest-platform.h: * src/maemo/modest-platform.c: Added modest_platform_connect_and_wait(), which calls tny_maemo_conic_device_connect() always in the main thread, by calling it in an idle handler and waiting for the idle handler to run. It should be in the main thread because it uses GTK+ UI code. It just returns TRUE if the device is already online. There is some nasty code to ensure that subsequent calls to modest_platform_connect_and_wait() just wait for the first one to finish, by checking repeatedly in another idle handler. This is necessary, because other threads (or even the main thread, via another idle handler) can call modest_platform_connect_and_wait() while modest_platform_connect_and_wait() is running. (modest_platform_connect_and_wait_if_network_account), (modest_platform_connect_and_wait_if_network_folderstore): Convenience functions that calls modest_platform_connect_and_wait() if the account or folder might want network access. * src/modest-mail-operation.c: (modest_mail_operation_update_account): * src/modest-ui-actions.c: (download_uncached_messages), (modest_ui_actions_on_rename_folder), (delete_folder), (modest_ui_actions_on_main_window_move_to), (modest_ui_actions_on_msg_view_window_move_to): * src/widgets/modest-folder-view.c: (drag_and_drop_from_folder_view): Offer a connection if we are offline. * src/modest-tny-account.c: (on_connection_status_changed): Document this as only handling errors during network operations in progress, and replace the idle code with a simple call to modest_platform_connect_and_wait(), which does this instead. pmo-trunk-r2560 --- diff --git a/ChangeLog2 b/ChangeLog2 index a24ca67..02a1277 100644 --- a/ChangeLog2 +++ b/ChangeLog2 @@ -1,3 +1,43 @@ +2007-07-04 Murray Cumming + + * src/maemo/modest-msg-view-window.c: + (modest_msg_view_window_select_next_message): + + * src/modest-platform.h: + * src/maemo/modest-platform.c: + Added modest_platform_connect_and_wait(), which calls + tny_maemo_conic_device_connect() always in the main thread, by calling it + in an idle handler and waiting for the idle handler to run. It should be + in the main thread because it uses GTK+ UI code. It just returns TRUE + if the device is already online. + + There is some nasty code to ensure that subsequent calls to + modest_platform_connect_and_wait() just wait for the first one to finish, + by checking repeatedly in another idle handler. This is necessary, + because other threads (or even the main thread, via another idle handler) + can call modest_platform_connect_and_wait() while + modest_platform_connect_and_wait() is running. + + (modest_platform_connect_and_wait_if_network_account), + (modest_platform_connect_and_wait_if_network_folderstore): + Convenience functions that calls modest_platform_connect_and_wait() if + the account or folder might want network access. + + * src/modest-mail-operation.c: + (modest_mail_operation_update_account): + * src/modest-ui-actions.c: (download_uncached_messages), + (modest_ui_actions_on_rename_folder), (delete_folder), + (modest_ui_actions_on_main_window_move_to), + (modest_ui_actions_on_msg_view_window_move_to): + * src/widgets/modest-folder-view.c: + (drag_and_drop_from_folder_view): + Offer a connection if we are offline. + + * src/modest-tny-account.c: (on_connection_status_changed): + Document this as only handling errors during network operations in progress, + and replace the idle code with a simple call to + modest_platform_connect_and_wait(), which does this instead. + 2007-07-03 Murray Cumming * src/modest-tny-account.c: diff --git a/src/gnome/modest-platform.c b/src/gnome/modest-platform.c index 0143b45..acd06b7 100644 --- a/src/gnome/modest-platform.c +++ b/src/gnome/modest-platform.c @@ -190,6 +190,13 @@ gboolean modest_platform_connect_and_wait (GtkWindow *parent_window) return TRUE; } +gboolean modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account) +{ + /* TODO: Do something with network-manager? + Otherwise, maybe it is safe to assume that we would already be online if we could be. */ + return TRUE; +} + gboolean modest_platform_set_update_interval (guint minutes) { /* TODO. */ diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index 57da7cc..a067cd3 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -1063,10 +1063,23 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); /* Msg download completed */ - if (flags & TNY_HEADER_FLAG_CACHED) + if (flags & TNY_HEADER_FLAG_CACHED) { + /* No download is necessary, because the message is cached: */ mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_OPEN, G_OBJECT(window)); - else + } else { + /* Offer the connection dialog if necessary: */ + TnyFolder *folder = tny_header_get_folder(header); + if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (folder))) { + g_object_unref (folder); + return FALSE; + } + if (folder) { + g_object_unref (folder); + folder = NULL; + } + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window)); + } /* New mail operation */ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); diff --git a/src/maemo/modest-platform.c b/src/maemo/modest-platform.c index 08a3de5..1b337fc 100644 --- a/src/maemo/modest-platform.c +++ b/src/maemo/modest-platform.c @@ -44,6 +44,8 @@ #include /* For alarm_event_add(), etc. */ #include #include +#include +#include #include #include #include @@ -883,15 +885,148 @@ modest_platform_run_information_dialog (GtkWindow *parent_window, gtk_widget_destroy (GTK_WIDGET (dialog)); } -gboolean modest_platform_connect_and_wait (GtkWindow *parent_window) + + +typedef struct { + GMainLoop* loop; +} UtilIdleData; + +static gboolean +on_idle_connect_and_wait(gpointer user_data) +{ + printf ("DEBUG: %s:\n", __FUNCTION__); TnyDevice *device = modest_runtime_get_device(); + if (!tny_device_is_online (device)) { + gdk_threads_enter(); + tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device), NULL); + gdk_threads_leave(); + } + + /* Allow the function that requested this idle callback to continue: */ + UtilIdleData *data = (UtilIdleData*)user_data; + if (data->loop) + g_main_loop_quit (data->loop); + return FALSE; /* Don't call this again. */ +} + +static gboolean connect_request_in_progress = FALSE; + +/* This callback is used when connect_and_wait() is already queued as an idle callback. + * This can happen because the gtk_dialog_run() for the connection dialog + * (at least in the fake scratchbox version) allows idle handlers to keep running. + */ +static gboolean +on_idle_wait_for_previous_connect_to_finish(gpointer user_data) +{ + gboolean result = FALSE; + TnyDevice *device = modest_runtime_get_device(); if (tny_device_is_online (device)) + result = FALSE; /* Stop trying. */ + else { + /* Keep trying until connect_request_in_progress is FALSE. */ + if (connect_request_in_progress) + result = TRUE; /* Keep trying */ + else { + printf ("DEBUG: %s: other idle has finished.\n", __FUNCTION__); + + result = FALSE; /* Stop trying, now that a result should be available. */ + } + } + + if (result == FALSE) { + /* Allow the function that requested this idle callback to continue: */ + UtilIdleData *data = (UtilIdleData*)user_data; + if (data->loop) + g_main_loop_quit (data->loop); + } + + return result; +} + + +gboolean modest_platform_connect_and_wait (GtkWindow *parent_window) +{ + if (connect_request_in_progress) + return FALSE; + + printf ("DEBUG: %s:\n", __FUNCTION__); + TnyDevice *device = modest_runtime_get_device(); + + if (tny_device_is_online (device)) { + printf ("DEBUG: %s: Already online.\n", __FUNCTION__); return TRUE; + } else + { + printf ("DEBUG: %s: tny_device_is_online() returned FALSE\n", __FUNCTION__); + } /* This blocks on the result: */ - return tny_maemo_conic_device_connect (TNY_MAEMO_CONIC_DEVICE (device), NULL); + UtilIdleData *data = g_slice_new0 (UtilIdleData); + + GMainContext *context = NULL; /* g_main_context_new (); */ + data->loop = g_main_loop_new (context, FALSE /* not running */); + + /* Cause the function to be run in an idle-handler, which is always + * in the main thread: + */ + if (!connect_request_in_progress) { + printf ("DEBUG: %s: First request\n", __FUNCTION__); + connect_request_in_progress = TRUE; + g_idle_add (&on_idle_connect_and_wait, data); + } + else { + printf ("DEBUG: %s: nth request\n", __FUNCTION__); + g_idle_add_full (G_PRIORITY_LOW, &on_idle_wait_for_previous_connect_to_finish, data, NULL); + } + + /* This main loop will run until the idle handler has stopped it: */ + printf ("DEBUG: %s: before g_main_loop_run()\n", __FUNCTION__); + GDK_THREADS_LEAVE(); + g_main_loop_run (data->loop); + GDK_THREADS_ENTER(); + printf ("DEBUG: %s: after g_main_loop_run()\n", __FUNCTION__); + connect_request_in_progress = FALSE; + printf ("DEBUG: %s: Finished\n", __FUNCTION__); + g_main_loop_unref (data->loop); + /* g_main_context_unref (context); */ + + g_slice_free (UtilIdleData, data); + + return tny_device_is_online (device); +} + +gboolean modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account) +{ + if (tny_account_get_account_type (account) == TNY_ACCOUNT_TYPE_STORE) { + if (!TNY_IS_CAMEL_POP_STORE_ACCOUNT (account) && + !TNY_IS_CAMEL_IMAP_STORE_ACCOUNT (account)) { + /* This must be a maildir account, which does not require a connection: */ + return TRUE; + } + } + + return modest_platform_connect_and_wait (parent_window); +} + +gboolean modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store) +{ + if (!folder_store) + return TRUE; /* Maybe it is something local. */ + + gboolean result = TRUE; + if (TNY_IS_FOLDER (folder_store)) { + /* Get the folder's parent account: */ + TnyAccount *account = tny_folder_get_account(TNY_FOLDER (folder_store)); + result = modest_platform_connect_and_wait_if_network_account (NULL, account); + g_object_unref (account); + } else if (TNY_IS_ACCOUNT (folder_store)) { + /* Use the folder store as an account: */ + result = modest_platform_connect_and_wait_if_network_account (NULL, TNY_ACCOUNT (folder_store)); + } + + return result; } void diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index c8af203..d9c203a 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -1177,6 +1177,13 @@ modest_mail_operation_update_account (ModestMailOperation *self, priv->done = 0; priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; + /* Make sure that we have a connection, and request one + * if necessary: + * TODO: Is there some way to trigger this for every attempt to + * use the network? */ + if (!modest_platform_connect_and_wait (NULL)) + goto error; + /* Get the Modest account */ modest_account = (TnyStoreAccount *) modest_tny_account_store_get_server_account (modest_runtime_get_account_store (), diff --git a/src/modest-platform.h b/src/modest-platform.h index 6f2a54b..511f730 100644 --- a/src/modest-platform.h +++ b/src/modest-platform.h @@ -211,6 +211,29 @@ void modest_platform_run_sort_dialog (GtkWindow *parent_window, */ gboolean modest_platform_connect_and_wait (GtkWindow *parent_window); + +/* + * modest_platform_connect_and_wait_if_network_account: + * @parent_window: the parent #GtkWindow for any interactive or progress feedback UI. + * @account: The account that might need a connection in subsequent operations. + * @return value: Whether a connection was made. Also returns TRUE if no connection is necessary. + * + * Like modest_platform_connect_and_wait(), but only attempts to make a connection if the + * account uses the network. For instance, this just returns TRUE for local maildir accounts. + */ +gboolean modest_platform_connect_and_wait_if_network_account (GtkWindow *parent_window, TnyAccount *account); + +/* + * modest_platform_connect_and_wait_if_network_account: + * @parent_window: the parent #GtkWindow for any interactive or progress feedback UI. + * @folder_store: The folder store (folder or account) that might need a connection in subsequent operations. + * @return value: Whether a connection was made. Also returns TRUE if no connection is necessary. + * + * Like modest_platform_connect_and_wait(), but only attempts to make a connection if the + * folder store uses the network. For instance, this just returns TRUE for local maildir folders. + */ +gboolean modest_platform_connect_and_wait_if_network_folderstore (GtkWindow *parent_window, TnyFolderStore *folder_store); + /** * modest_platform_set_update_interval: * @minutes: The number of minutes between updates, or 0 for no updates. diff --git a/src/modest-tny-account.c b/src/modest-tny-account.c index 7ca1808..aeb957f 100644 --- a/src/modest-tny-account.c +++ b/src/modest-tny-account.c @@ -27,12 +27,12 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include #include #include -#include #include #include #include @@ -148,70 +148,26 @@ modest_tny_account_get_special_folder (TnyAccount *account, return special_folder; } -typedef struct -{ - GSourceFunc func; - GMainLoop* loop; -} UtilIdleData; - -static gboolean util_on_idle(gpointer user_data) -{ - /* We are now in the main thread, - * so we can call the function: - */ - UtilIdleData *idle_data = (UtilIdleData*)user_data; - if (idle_data && idle_data->func) - (*(idle_data->func))(NULL); - - /* Stop the main loop so that the caller can continue: */ - if (idle_data->loop) - g_main_loop_quit (idle_data->loop); - - return FALSE; /* Stop calling this callback. */ -} - -static void -util_run_in_main_thread_and_wait(GSourceFunc function) -{ - UtilIdleData *data = g_slice_new0 (UtilIdleData); - data->func = function; - data->loop = g_main_loop_new (NULL, FALSE /* not running */); - - /* Cause the function to be run in an idle-handler, which is always - * in the main thread: - */ - g_idle_add (util_on_idle, data); - - /* This main loop will run until the idle handler has stopped it: */ - g_main_loop_run (data->loop); - g_main_loop_unref (data->loop); - - g_slice_free (UtilIdleData, data); -} - -static gboolean -connect_and_wait(gpointer user_data) -{ - modest_platform_connect_and_wait(NULL); - return TRUE; /* Ignored */ -} - static void on_connection_status_changed (TnyAccount *account, TnyConnectionStatus status, gpointer user_data) { printf ("DEBUG: %s: status=%d\n", __FUNCTION__, status); if (status == TNY_CONNECTION_STATUS_DISCONNECTED) { - /* We are trying to use the network with an account, - * but the accounts are set as offline, because our TnyDevice is offline, + /* A tinymail network operation failed, and tinymail then noticed that + * the account is offline, because our TnyDevice is offline, * because libconic says we are offline. - * So ask the user to go online: + * So ask the user to go online again. + * + * Note that this signal will not be emitted if the account was offline + * when the network operation was first attempted. For those cases, + * the application must do its own explicit checks. * * We make sure that this UI is shown in the main thread, to avoid races, * because tinymail does not guarantee that this signal handler will be called * in the main thread. */ - util_run_in_main_thread_and_wait (&connect_and_wait); + modest_platform_connect_and_wait (NULL); } else if (status == TNY_CONNECTION_STATUS_CONNECTED_BROKEN) { printf ("DEBUG: %s: Connection broken. Forcing TnyDevice offline.\n", __FUNCTION__); diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index dbbbf28..617dca5 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -1011,6 +1011,10 @@ download_uncached_messages (TnyList *header_list, GtkWindow *win) uncached_messages)); if (response == GTK_RESPONSE_CANCEL) retval = FALSE; + else { + /* If a download will be necessary, make sure that we have a connection: */ + retval = modest_platform_connect_and_wait(win); + } } return retval; } @@ -2004,6 +2008,13 @@ modest_ui_actions_on_rename_folder (GtkAction *action, return; 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 (NULL, folder)) { + g_object_unref (G_OBJECT (folder)); + return; + } + if (folder && TNY_IS_FOLDER (folder)) { gchar *folder_name; @@ -2072,9 +2083,16 @@ delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) if (!TNY_IS_FOLDER (folder)) { modest_platform_run_information_dialog (GTK_WINDOW (main_window), _("mail_in_ui_folder_delete_error")); + g_object_unref (G_OBJECT (folder)); return ; } + /* Offer the connection dialog if necessary: */ + if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) { + g_object_unref (G_OBJECT (folder)); + return; + } + /* Ask the user */ message = g_strdup_printf (_("mcen_nc_delete_folder_text"), tny_folder_get_name (TNY_FOLDER (folder))); @@ -3153,7 +3171,7 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, { GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL; GtkWidget *header_view = NULL; - gint result; + gint result = 0; TnyFolderStore *folder_store = NULL; ModestMailOperation *mail_op = NULL; @@ -3183,39 +3201,47 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store)) goto end; + /* Offer the connection dialog if necessary: */ + 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)); - /* Clean folder on header view before moving it */ - modest_header_view_clear (MODEST_HEADER_VIEW (header_view)); + /* Offer the connection dialog if necessary: */ + if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) { - if (TNY_IS_FOLDER (src_folder)) { - mail_op = - modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, + /* 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); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - 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)); - } + 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)); + } - /* Frees */ - g_object_unref (G_OBJECT (src_folder)); + /* Frees */ + g_object_unref (G_OBJECT (src_folder)); + } } else { if (gtk_widget_is_focus (header_view)) { - TnyList *headers; - gint response; + TnyList *headers = NULL; + gint response = 0; + /* TODO: Check for connection if the headers are on a network account. */ headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view)); /* Ask for user confirmation */ @@ -3245,9 +3271,11 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, g_object_unref (headers); } } + end: if (folder_store != NULL) g_object_unref (folder_store); + gtk_widget_destroy (dialog); } @@ -3261,10 +3289,10 @@ modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, ModestMsgViewWindow *win) { GtkWidget *dialog, *folder_view, *tree_view = NULL; - gint result; - ModestMainWindow *main_window; - TnyHeader *header; - TnyList *headers; + gint result = 0; + ModestMainWindow *main_window = NULL; + TnyHeader *header = NULL; + TnyList *headers = NULL; /* Get the folder view */ main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ())); @@ -3286,37 +3314,52 @@ modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win)); g_return_if_fail (header != NULL); - headers = tny_simple_list_new (); - tny_list_prepend (headers, G_OBJECT (header)); - g_object_unref (header); - - /* Ask user for confirmation. MSG-NOT404 */ + /* Offer the connection dialog if necessary: */ + /* TODO: What's the extra g_object_ref() for? Isn't this leaking a ref? */ folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (g_object_ref (tree_view))); - response = msgs_move_to_confirmation (GTK_WINDOW (win), + TnyFolder *header_folder = tny_header_get_folder(header); + if (modest_platform_connect_and_wait_if_network_folderstore (NULL, folder_store) && + modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (header_folder))) { + + headers = tny_simple_list_new (); + tny_list_prepend (headers, G_OBJECT (header)); + g_object_unref (header); + + /* Ask user for confirmation. MSG-NOT404 */ + response = msgs_move_to_confirmation (GTK_WINDOW (win), TNY_FOLDER (folder_store), headers); - /* Transfer current msg */ - if (response == GTK_RESPONSE_OK) { - ModestMailOperation *mail_op; + /* Transfer current msg */ + if (response == GTK_RESPONSE_OK) { + ModestMailOperation *mail_op; - /* Create mail op */ - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win)); - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), + /* Create mail op */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - /* Transfer messages */ - modest_mail_operation_xfer_msgs (mail_op, + /* Transfer messages */ + modest_mail_operation_xfer_msgs (mail_op, headers, TNY_FOLDER (folder_store), TRUE, transfer_msgs_from_viewer_cb, NULL); - g_object_unref (G_OBJECT (mail_op)); + g_object_unref (G_OBJECT (mail_op)); + } } - g_object_unref (headers); - g_object_unref (folder_store); + + if (header_folder) + g_object_unref (header_folder); + + if (headers) + g_object_unref (headers); + + if (folder_store) + g_object_unref (folder_store); } + gtk_widget_destroy (dialog); } diff --git a/src/widgets/modest-folder-view.c b/src/widgets/modest-folder-view.c index 961be2a..498ab17 100644 --- a/src/widgets/modest-folder-view.c +++ b/src/widgets/modest-folder-view.c @@ -1414,10 +1414,10 @@ drag_and_drop_from_folder_view (GtkTreeModel *source_model, GtkSelectionData *selection_data, DndHelper *helper) { - ModestMailOperation *mail_op; + ModestMailOperation *mail_op = NULL; GtkTreeIter parent_iter, iter; - TnyFolderStore *parent_folder; - TnyFolder *folder; + TnyFolderStore *parent_folder = NULL; + TnyFolder *folder = NULL; /* Check if the drag is possible */ /* if (!gtk_tree_path_compare (helper->source_row, dest_row) || */ @@ -1442,22 +1442,26 @@ drag_and_drop_from_folder_view (GtkTreeModel *source_model, TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &folder, -1); - /* Do the mail operation */ - mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, + /* Offer the connection dialog if necessary, for the destination parent folder and source folder: */ + if (modest_platform_connect_and_wait_if_network_folderstore (NULL, parent_folder) && + modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (folder))) { + /* Do the mail operation */ + mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, NULL, modest_ui_actions_move_folder_error_handler, NULL); - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - g_signal_connect (G_OBJECT (mail_op), "progress-changed", - G_CALLBACK (on_progress_changed), helper); + g_signal_connect (G_OBJECT (mail_op), "progress-changed", + G_CALLBACK (on_progress_changed), helper); - modest_mail_operation_xfer_folder (mail_op, + modest_mail_operation_xfer_folder (mail_op, folder, parent_folder, helper->delete_source, NULL, NULL); + } /* Frees */ g_object_unref (G_OBJECT (parent_folder));