* Fixed drag&drop for folders
authorSergio Villar Senin <svillar@igalia.com>
Mon, 21 May 2007 12:53:48 +0000 (12:53 +0000)
committerSergio Villar Senin <svillar@igalia.com>
Mon, 21 May 2007 12:53:48 +0000 (12:53 +0000)
* 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
src/modest-mail-operation.c
src/modest-mail-operation.h
src/modest-ui-actions.c
src/widgets/modest-folder-view.c
src/widgets/modest-header-view.c

index ce8808e..db14af7 100644 (file)
@@ -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,
index e07075b..9fee69a 100644 (file)
@@ -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);
 }
index caae5fb..bd7ca2c 100644 (file)
@@ -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__ */
index a9ecd76..8b9de02 100644 (file)
@@ -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);
        }
 }
 
index e16e202..4f12ab5 100644 (file)
@@ -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;
 }
index 796619d..469c4cd 100644 (file)
@@ -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