From 6fa3391b965296264fcac2a96e3760f369cc1125 Mon Sep 17 00:00:00 2001 From: Sergio Villar Senin Date: Mon, 21 May 2007 12:53:48 +0000 Subject: [PATCH] * Fixed drag&drop for folders * Fixed drag&drop for headers * Added progress-changed notification to all mail operations when they finish * Fixed a bug when selecting folders in the UI actions * Added some debug code to the mail operation queue, prints mail operation errors pmo-trunk-r1938 --- src/modest-mail-operation-queue.c | 9 ++-- src/modest-mail-operation.c | 104 ++++++++++++++++++------------------- src/modest-mail-operation.h | 12 ----- src/modest-ui-actions.c | 17 +++--- src/widgets/modest-folder-view.c | 34 ++++++++---- src/widgets/modest-header-view.c | 11 ++-- 6 files changed, 93 insertions(+), 94 deletions(-) diff --git a/src/modest-mail-operation-queue.c b/src/modest-mail-operation-queue.c index ce8808e..db14af7 100644 --- a/src/modest-mail-operation-queue.c +++ b/src/modest-mail-operation-queue.c @@ -194,9 +194,12 @@ modest_mail_operation_queue_remove (ModestMailOperationQueue *self, g_queue_remove (priv->op_queue, mail_op); g_mutex_unlock (priv->queue_lock); -/* /\* HACK see the documentation of the function. Remove this */ -/* call when tinymail provides accurate progress values *\/ */ -/* _modest_mail_operation_notify_end (mail_op); */ + { + const GError *err; + err = modest_mail_operation_get_error (mail_op); + if (err) + g_printerr (err->message); + } /* Notify observers */ g_signal_emit (self, signals[QUEUE_CHANGED_SIGNAL], 0, diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index e07075b..9fee69a 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -70,6 +70,7 @@ static void get_msg_status_cb (GObject *obj, TnyStatus *status, gpointer user_data); +static void modest_mail_operation_notify_end (ModestMailOperation *self); enum _ModestMailOperationSignals { @@ -306,8 +307,8 @@ modest_mail_operation_send_mail (ModestMailOperation *self, } } - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); } void @@ -403,7 +404,7 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self, goto cleanup; } - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + modest_mail_operation_notify_end (self); /* Free */ cleanup: @@ -466,8 +467,7 @@ notify_update_account_queue (gpointer data) { ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data); - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), - mail_op); + modest_mail_operation_notify_end (mail_op); g_object_unref (mail_op); return FALSE; @@ -567,9 +567,9 @@ update_account_thread (gpointer thr_user_data) } out: - /* Notify the queue. Note that the info could be freed before - this idle happens, but the mail operation will be still - alive */ + /* Notify about operation end. Note that the info could be + freed before this idle happens, but the mail operation will + be still alive */ g_idle_add (notify_update_account_queue, info->mail_op); /* Frees */ @@ -614,8 +614,7 @@ modest_mail_operation_update_account (ModestMailOperation *self, g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, "cannot get tny store account for %s\n", account_name); - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), - self); + modest_mail_operation_notify_end (self); return FALSE; } @@ -629,8 +628,7 @@ modest_mail_operation_update_account (ModestMailOperation *self, g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, "cannot get tny transport account for %s\n", account_name); - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), - self); + modest_mail_operation_notify_end (self); return FALSE; } @@ -688,8 +686,8 @@ modest_mail_operation_cancel (ModestMailOperation *self) /* Set new status */ priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED; - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); return TRUE; } @@ -783,8 +781,8 @@ modest_mail_operation_create_folder (ModestMailOperation *self, CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED); } - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); return new_folder; } @@ -839,8 +837,8 @@ modest_mail_operation_remove_folder (ModestMailOperation *self, g_object_unref (G_OBJECT (account)); end: - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); } void @@ -879,13 +877,13 @@ modest_mail_operation_rename_folder (ModestMailOperation *self, } - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); } static void transfer_folder_status_cb (GObject *obj, - TnyStatus *status, + TnyStatus *status, gpointer user_data) { XFerMsgAsyncHelper *helper = NULL; @@ -896,12 +894,7 @@ transfer_folder_status_cb (GObject *obj, g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_COPY_FOLDER); helper = (XFerMsgAsyncHelper *) user_data; - g_return_if_fail (helper != NULL); - - /* Temporary FIX: useful when tinymail send us status - information *after* calling the function callback */ - if (!MODEST_IS_MAIL_OPERATION (helper->mail_op)) - return; + g_return_if_fail (helper != NULL); self = helper->mail_op; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); @@ -912,7 +905,6 @@ transfer_folder_status_cb (GObject *obj, priv->done = status->position; priv->total = status->of_total; - g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL); } @@ -932,7 +924,7 @@ transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, if (*err) { priv->error = g_error_copy (*err); priv->done = 0; - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; } else if (cancelled) { priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, @@ -948,11 +940,11 @@ transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, g_slice_free (XFerFolderAsyncHelper, helper); g_object_unref (folder); g_object_unref (into); - if (new_folder != NULL) + if (new_folder != NULL) g_object_unref (new_folder); - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); } TnyFolder * @@ -986,8 +978,8 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self, &(priv->error)); } - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); return new_folder; } @@ -1015,13 +1007,12 @@ modest_mail_operation_xfer_folder_async (ModestMailOperation *self, /* The moveable restriction is applied also to copy operation */ rules = modest_tny_folder_get_rules (TNY_FOLDER (parent)); if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) { - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES, _("FIXME: unable to rename")); /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + modest_mail_operation_notify_end (self); } else { helper = g_slice_new0 (XFerFolderAsyncHelper); helper->mail_op = self; @@ -1125,8 +1116,8 @@ get_msg_cb (TnyFolder *folder, if (helper->pending_ops == 0) { g_slice_free (GetMsgAsyncHelper, helper); - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); } } @@ -1294,7 +1285,7 @@ get_msgs_full_thread (gpointer thr_user_data) tny_iterator_next (iter); } - /* Notify the queue */ + /* Notify about operation end */ g_idle_add (notify_update_account_queue, info->mail_op); /* Free thread resources. Will be called after all previous idles */ @@ -1369,7 +1360,7 @@ modest_mail_operation_get_msgs_full (ModestMailOperation *self, MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER, _("emev_ni_ui_imap_msg_sizelimit_error")); /* Remove from queue and free resources */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + modest_mail_operation_notify_end (self); if (notify) notify (user_data); } @@ -1439,8 +1430,8 @@ modest_mail_operation_remove_msg (ModestMailOperation *self, /* Free */ g_object_unref (G_OBJECT (folder)); - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); } static void @@ -1458,11 +1449,6 @@ transfer_msgs_status_cb (GObject *obj, helper = (XFerMsgAsyncHelper *) user_data; g_return_if_fail (helper != NULL); - /* Temporary FIX: useful when tinymail send us status - information *after* calling the function callback */ - if (!MODEST_IS_MAIL_OPERATION (helper->mail_op)) - return; - self = helper->mail_op; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); @@ -1515,8 +1501,8 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer g_slice_free (XFerMsgAsyncHelper, helper); g_object_unref (folder); - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); } void @@ -1601,8 +1587,8 @@ on_refresh_folder (TnyFolder *folder, /* Free */ g_object_unref (folder); - /* Notify the queue */ - modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); + /* Notify about operation end */ + modest_mail_operation_notify_end (self); } static void @@ -1652,8 +1638,20 @@ modest_mail_operation_refresh_folder (ModestMailOperation *self, self); } -void -_modest_mail_operation_notify_end (ModestMailOperation *self) +/** + * + * It's used by the mail operation queue to notify the observers + * attached to that signal that the operation finished. We need to use + * that because tinymail does not give us the progress of a given + * operation when it finishes (it directly calls the operation + * callback). + */ +static void +modest_mail_operation_notify_end (ModestMailOperation *self) { + /* Notify the observers about the mail opertation end */ g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL); + + /* Notify the queue */ + modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self); } diff --git a/src/modest-mail-operation.h b/src/modest-mail-operation.h index caae5fb..bd7ca2c 100644 --- a/src/modest-mail-operation.h +++ b/src/modest-mail-operation.h @@ -555,18 +555,6 @@ gboolean modest_mail_operation_cancel (ModestMailOperation *self); void modest_mail_operation_refresh_folder (ModestMailOperation *self, TnyFolder *folder); -/** - * - * This function is a workarround. It emits the progress-changed - * signal. It's used by the mail operation queue to notify the - * observers attached to that signal that the operation finished. We - * need to use that for the moment because tinymail does not give us - * the progress of a given operation very well. So we must delete it - * when tinymail has that functionality and remove the call to it in - * the queue as well. - */ -void _modest_mail_operation_notify_end (ModestMailOperation *self); - G_END_DECLS #endif /* __MODEST_MAIL_OPERATION_H__ */ diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index a9ecd76..8b9de02 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -1073,14 +1073,18 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view, conf = modest_runtime_get_conf (); - if (TNY_IS_FOLDER (folder_store)) { - - if (selected) { + if (TNY_IS_ACCOUNT (folder_store)) { + /* Update active account */ + set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window)); + /* Show account details */ + modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS); + } else { + if (TNY_IS_FOLDER (folder_store) && selected) { /* Update the active account */ account = tny_folder_get_account (TNY_FOLDER (folder_store)); set_active_account_from_tny_account (account, MODEST_WINDOW (main_window)); g_object_unref (account); - + /* Set folder on header view */ modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS); @@ -1095,11 +1099,6 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view, modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY); modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL); } - } else if (TNY_IS_ACCOUNT (folder_store)) { - /* Update active account */ - set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window)); - /* Show account details */ - modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS); } } diff --git a/src/widgets/modest-folder-view.c b/src/widgets/modest-folder-view.c index e16e202..4f12ab5 100644 --- a/src/widgets/modest-folder-view.c +++ b/src/widgets/modest-folder-view.c @@ -906,7 +906,6 @@ on_drag_data_get (GtkWidget *widget, gtk_tree_selection_get_selected (selection, &model, &iter); source_row = gtk_tree_model_get_path (model, &iter); - gtk_tree_set_row_drag_data (selection_data, model, source_row); @@ -1026,10 +1025,11 @@ drag_and_drop_from_folder_view (GtkTreeModel *source_model, TnyFolder *folder; /* Check if the drag is possible */ - if (!gtk_tree_path_compare (helper->source_row, dest_row) || - !gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (dest_model), - dest_row, - selection_data)) { +/* if (!gtk_tree_path_compare (helper->source_row, dest_row) || */ +/* !gtk_tree_drag_dest_row_drop_possible (GTK_TREE_DRAG_DEST (dest_model), */ +/* dest_row, */ +/* selection_data)) { */ + if (!gtk_tree_path_compare (helper->source_row, dest_row)) { gtk_drag_finish (helper->context, FALSE, FALSE, helper->time); gtk_tree_path_free (helper->source_row); @@ -1090,17 +1090,28 @@ on_drag_data_received (GtkWidget *widget, /* Do not allow further process */ g_signal_stop_emission_by_name (widget, "drag-data-received"); + source_widget = gtk_drag_get_source_widget (context); - /* Get the action (FIXME: only copy is currently implemented */ -/* if (context->action == GDK_ACTION_MOVE) */ -/* delete_source = TRUE; */ + /* Get the action */ + if (context->action == GDK_ACTION_MOVE) { + delete_source = TRUE; + + /* Notify that there is no folder selected. We need to + do this in order to update the headers view (and + its monitors, because when moving, the old folder + won't longer exist. We can not wait for the end of + the operation, because the operation won't start if + the folder is in use */ + if (helper->delete_source && source_widget == widget) + g_signal_emit (G_OBJECT (widget), + signals[FOLDER_SELECTION_CHANGED_SIGNAL], 0, NULL, TRUE); + } /* Check if the get_data failed */ if (selection_data == NULL || selection_data->length < 0) gtk_drag_finish (context, success, FALSE, time); /* Get the models */ - source_widget = gtk_drag_get_source_widget (context); gtk_tree_get_row_drag_data (selection_data, &source_model, &source_row); @@ -1253,7 +1264,7 @@ on_drag_motion (GtkWidget *widget, /* Do not allow drops between folders */ if (!dest_row || - pos == GTK_TREE_VIEW_DROP_BEFORE || + pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_AFTER) { gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW (widget), NULL, 0); gdk_drag_status(context, 0, time); @@ -1268,7 +1279,6 @@ on_drag_motion (GtkWidget *widget, gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), dest_row, pos); priv->timer_expander = g_timeout_add (500, expand_row_timeout, widget); } - gtk_tree_path_free (dest_row); /* Select the desired action. By default we pick MOVE */ suggested_action = GDK_ACTION_MOVE; @@ -1283,6 +1293,8 @@ on_drag_motion (GtkWidget *widget, gdk_drag_status(context, GDK_ACTION_DEFAULT, time); out: + if (dest_row) + gtk_tree_path_free (dest_row); g_signal_stop_emission_by_name (widget, "drag-motion"); return valid_location; } diff --git a/src/widgets/modest-header-view.c b/src/widgets/modest-header-view.c index 796619d..469c4cd 100644 --- a/src/widgets/modest-header-view.c +++ b/src/widgets/modest-header-view.c @@ -919,12 +919,12 @@ modest_header_view_set_folder (ModestHeaderView *self, TnyFolder *folder) } else { g_mutex_lock (priv->observers_lock); - modest_header_view_set_model (GTK_TREE_VIEW (self), NULL); if (priv->monitor) { tny_folder_monitor_stop (priv->monitor); g_object_unref (G_OBJECT (priv->monitor)); priv->monitor = NULL; } + modest_header_view_set_model (GTK_TREE_VIEW (self), NULL); g_mutex_unlock (priv->observers_lock); } @@ -1189,11 +1189,11 @@ drag_data_get_cb (GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint time, gpointer data) { - GtkTreeModel *model; + GtkTreeModel *model = NULL; GtkTreeIter iter; - GtkTreePath *source_row; + GtkTreePath *source_row = NULL; - source_row = get_selected_row (GTK_TREE_VIEW(widget), &model); + source_row = get_selected_row (GTK_TREE_VIEW (widget), &model); if ((source_row == NULL) || (!gtk_tree_model_get_iter(model, &iter, source_row))) return; switch (info) { @@ -1220,8 +1220,7 @@ drag_data_get_cb (GtkWidget *widget, GdkDragContext *context, /* Header view drag types */ const GtkTargetEntry header_view_drag_types[] = { { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP, MODEST_HEADER_ROW }, - { "text/uri-list", 0, MODEST_MSG }, - + { "text/uri-list", 0, MODEST_MSG }, }; static void -- 1.7.9.5