2007-07-25 Murray Cumming <murrayc@murrayc.com>
[modest] / src / widgets / modest-folder-view.c
index da0d5a8..e026ccb 100644 (file)
@@ -126,11 +126,14 @@ static gint         expand_row_timeout     (gpointer data);
 
 static void         setup_drag_and_drop    (GtkTreeView *self);
 
-static gboolean     _clipboard_set_selected_data (ModestFolderView *folder_view, gboolean delete);
+static gboolean     _clipboard_set_selected_data (ModestFolderView *folder_view, 
+                                                 gboolean delete);
 
 static void         _clear_hidding_filter (ModestFolderView *folder_view);
 
-static void          on_row_changed_maybe_select_folder (GtkTreeModel *tree_model, GtkTreePath  *path, GtkTreeIter  *iter,
+static void          on_row_changed_maybe_select_folder (GtkTreeModel     *tree_model, 
+                                                        GtkTreePath      *path, 
+                                                        GtkTreeIter      *iter,
                                                         ModestFolderView *self);
 
 enum {
@@ -806,8 +809,18 @@ on_account_removed (TnyAccountStore *account_store,
 
        /* If the removed account is the currently viewed one then
           clear the configuration value. The new visible account will be the default account */
-       if (!strcmp (priv->visible_account_id, tny_account_get_id (account))) {
+       if (priv->visible_account_id &&
+           !strcmp (priv->visible_account_id, tny_account_get_id (account))) {
+
+               /* Clear the current visible account_id */
                modest_folder_view_set_account_id_of_visible_server_account (self, NULL);
+
+               /* Call the restore method, this will set the new visible account */
+               modest_widget_memory_restore (modest_runtime_get_conf(), G_OBJECT(self),
+                                             MODEST_CONF_FOLDER_VIEW_KEY);
+
+               /* Select the INBOX */
+               modest_folder_view_select_first_inbox_or_local (self);
        }
 }
 
@@ -823,7 +836,10 @@ on_account_update (TnyAccountStore *account_store,
        self = MODEST_FOLDER_VIEW (user_data);
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
 
-       if (!priv->visible_account_id)
+       /* If we're adding a new account, and there is no previous
+          one, we need to select the visible server account */
+       if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ONE &&
+           !priv->visible_account_id)
                modest_widget_memory_restore (modest_runtime_get_conf(), G_OBJECT(self),
                                              MODEST_CONF_FOLDER_VIEW_KEY);
 
@@ -876,8 +892,9 @@ modest_folder_view_on_map (ModestFolderView *self,
                   be a bug, because the INBOX is not selected, but we
                   need to rewrite some parts of Modest to avoid the
                   deathlock situation */
-/*             modest_folder_view_select_first_inbox_or_local (self); */
+               /* TODO: check if this is still the case */
                priv->reselect = FALSE;
+               modest_folder_view_select_first_inbox_or_local (self);
        }
        return FALSE;
 }
@@ -936,7 +953,7 @@ filter_row (GtkTreeModel *model,
        guint i;
        gboolean found = FALSE;
        gboolean cleared = FALSE;
-       
+
        g_return_val_if_fail (MODEST_IS_FOLDER_VIEW (data), FALSE);
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (data);
 
@@ -961,11 +978,17 @@ filter_row (GtkTreeModel *model,
        
                        /* If it isn't a special folder, 
                         * don't show it unless it is the visible account: */
-                       if (!modest_tny_account_is_virtual_local_folders (acc) &&
-                               strcmp (account_id, MODEST_MMC_ACCOUNT_ID)) { 
+                       if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ONE &&
+                           !modest_tny_account_is_virtual_local_folders (acc) &&
+                           strcmp (account_id, MODEST_MMC_ACCOUNT_ID)) {
+                               
                                /* Show only the visible account id */
-                               if (priv->visible_account_id && strcmp (account_id, priv->visible_account_id))
+                               if (priv->visible_account_id) {
+                                       if (strcmp (account_id, priv->visible_account_id))
+                                               retval = FALSE;
+                               } else {
                                        retval = FALSE;
+                               }                               
                        }
                        
                        /* Never show these to the user. They are merged into one folder 
@@ -974,8 +997,6 @@ filter_row (GtkTreeModel *model,
                                retval = FALSE;
                }
        }
-       
-       /* The virtual local-folders folder store is also shown by default. */
 
        /* Check hiding (if necessary) */
        cleared = modest_email_clipboard_cleared (priv->clipboard);            
@@ -989,14 +1010,27 @@ filter_row (GtkTreeModel *model,
                retval = !found;
        }
        
+       
+       /* If this is a move to dialog, hide Sent, Outbox and Drafts
+       folder as no message can be move there according to UI specs */
        if (!priv->show_non_move)
        {
                switch (type)
                {
                        case TNY_FOLDER_TYPE_OUTBOX:
                        case TNY_FOLDER_TYPE_SENT:
+                       case TNY_FOLDER_TYPE_DRAFTS:
                                retval = FALSE;
                                break;
+                       case TNY_FOLDER_TYPE_UNKNOWN:
+                       case TNY_FOLDER_TYPE_NORMAL:
+                               type = modest_tny_folder_guess_folder_type(TNY_FOLDER(instance));
+                               if (type == TNY_FOLDER_TYPE_OUTBOX || type == TNY_FOLDER_TYPE_SENT
+                                               || type == TNY_FOLDER_TYPE_DRAFTS)
+                               {
+                                       retval = FALSE;
+                               }
+                               break;
                        default:
                                break;  
                }       
@@ -1056,7 +1090,7 @@ modest_folder_view_update_model (ModestFolderView *self,
                                              GTK_SORT_ASCENDING);
        gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sortable),
                                         TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN,
-                                cmp_rows, NULL, NULL);
+                                        cmp_rows, NULL, NULL);
 
        /* Create filter model */
        filter_model = gtk_tree_model_filter_new (sortable, NULL);
@@ -1064,13 +1098,6 @@ modest_folder_view_update_model (ModestFolderView *self,
                                                filter_row,
                                                self,
                                                NULL);
-/*     if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ONE) { */
-/*             filter_model = gtk_tree_model_filter_new (sortable, NULL); */
-/*             gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter_model), */
-/*                                                     filter_row, */
-/*                                                     self, */
-/*                                                     NULL); */
-/*     } */
 
        /* Set new model */
        gtk_tree_view_set_model (GTK_TREE_VIEW(self), filter_model);
@@ -1079,16 +1106,9 @@ modest_folder_view_update_model (ModestFolderView *self,
        g_signal_connect (G_OBJECT(filter_model), "row-inserted",
                          (GCallback)on_row_changed_maybe_select_folder, self);
 
-       
-
-/*     gtk_tree_view_set_model (GTK_TREE_VIEW(self),  */
-/*                              (filter_model) ? filter_model : sortable); */
 
        g_object_unref (model);
-       g_object_unref (filter_model);
-/*     if (filter_model) */
-/*             g_object_unref (filter_model); */
-                       
+       g_object_unref (filter_model);          
        g_object_unref (sortable);
 
        /* Force a reselection of the INBOX next time the widget is shown */
@@ -1133,12 +1153,14 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
        
        /* Current folder was unselected */
        if (priv->cur_folder_store) {
+               g_signal_emit (G_OBJECT(tree_view), signals[FOLDER_SELECTION_CHANGED_SIGNAL], 0,
+                      priv->cur_folder_store, FALSE);
+
                if (TNY_IS_FOLDER(priv->cur_folder_store))
-                       tny_folder_sync_async (TNY_FOLDER(priv->cur_folder_store), FALSE, NULL, NULL, NULL);
+                       tny_folder_sync_async (TNY_FOLDER(priv->cur_folder_store),
+                                              FALSE, NULL, NULL, NULL);
                /* FALSE --> don't expunge the messages */
 
-               g_signal_emit (G_OBJECT(tree_view), signals[FOLDER_SELECTION_CHANGED_SIGNAL], 0,
-                              priv->cur_folder_store, FALSE);
                g_object_unref (priv->cur_folder_store);
                priv->cur_folder_store = NULL;
        }
@@ -1224,7 +1246,7 @@ static gint
 cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
          gpointer user_data)
 {
-       gint cmp;
+       gint cmp = 0;
        gchar *name1 = NULL;
        gchar *name2 = NULL;
        TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
@@ -1248,7 +1270,7 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
           folder copy/move actually occurs, so there could be
           situations where the model to be drawn is not correct */
        if (!folder1 || !folder2)
-               return 0;
+               goto finish;
 
        if (type == TNY_FOLDER_TYPE_ROOT) {
                /* Compare the types, so that 
@@ -1275,16 +1297,17 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
                        const gchar *account_id = account1 ? tny_account_get_id (account1) : NULL;
                        const gchar *account_id2 = account2 ? tny_account_get_id (account2) : NULL;
        
-                       if (!account_id && !account_id2)
-                               return 0;
-                       else if (!account_id)
-                               return -1;
-                       else if (!account_id2)
-                               return +1;
-                       else if (!strcmp (account_id, MODEST_MMC_ACCOUNT_ID))
+                       if (!account_id && !account_id2) {
+                               cmp = 0;
+                       } else if (!account_id) {
+                               cmp = -1;
+                       } else if (!account_id2) {
                                cmp = +1;
-                       else
+                       } else if (!strcmp (account_id, MODEST_MMC_ACCOUNT_ID)) {
+                               cmp = +1;
+                       } else {
                                cmp = modest_text_utils_utf8_strcmp (name1, name2, TRUE);
+                       }
                }
        } else {
                gint cmp1 = 0, cmp2 = 0;
@@ -1320,7 +1343,8 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
                else 
                        cmp = (cmp1 - cmp2);
        }
-       
+
+finish:        
        if (folder1)
                g_object_unref(G_OBJECT(folder1));
        if (folder2)
@@ -1454,7 +1478,10 @@ drag_and_drop_from_header_view (GtkTreeModel *source_model,
        }
 
        /* Transfer message */
-       mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, NULL);
+       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 (),
                                         mail_op);
        g_signal_connect (G_OBJECT (mail_op), "progress-changed",
@@ -1539,12 +1566,13 @@ drag_and_drop_from_folder_view (GtkTreeModel     *source_model,
                                           helper->delete_source,
                                           NULL,
                                           NULL);
+
+               g_object_unref (G_OBJECT (mail_op));    
        }
        
        /* Frees */
        g_object_unref (G_OBJECT (parent_folder));
        g_object_unref (G_OBJECT (folder));
-       g_object_unref (G_OBJECT (mail_op));
 }
 
 /*
@@ -1986,11 +2014,6 @@ find_inbox_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *inbox_iter
                                    TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &name,
                                    TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, 
                                    &type, -1);
-
-               /*
-               printf ("DEBUG: %s: name=%s, type=%d, TNY_FOLDER_TYPE_INBOX=%d\n", 
-                       __FUNCTION__, name, type, TNY_FOLDER_TYPE_INBOX);
-               */
                        
                gboolean result = FALSE;
                if (type == TNY_FOLDER_TYPE_INBOX) {
@@ -2104,21 +2127,27 @@ on_row_changed_maybe_select_folder (GtkTreeModel *tree_model, GtkTreePath  *path
        if (!MODEST_IS_FOLDER_VIEW(self))
                return;
        
-       g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
        
-       sel  = gtk_tree_view_get_selection (GTK_TREE_VIEW(self));
-       
        if (priv->folder_to_select) {
+               
                if (!modest_folder_view_select_folder (self, priv->folder_to_select,
                                                       FALSE)) {
+                       GtkTreePath *path;
+                       path = gtk_tree_model_get_path (tree_model, iter);
+                       gtk_tree_view_expand_to_path (GTK_TREE_VIEW(self), path);
+                       
                        sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+
                        gtk_tree_selection_select_iter (sel, iter);
-                       g_debug ("could not find changed folder");
-               } 
+                       gtk_tree_view_set_cursor (GTK_TREE_VIEW(self), path, NULL, FALSE);
+
+                       gtk_tree_path_free (path);
+               
+               }
                g_object_unref (priv->folder_to_select);
                priv->folder_to_select = NULL;
-       } 
+       }
 }
 
 
@@ -2137,6 +2166,10 @@ modest_folder_view_select_folder (ModestFolderView *self, TnyFolder *folder,
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
 
        if (after_change) {
+
+               sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+               gtk_tree_selection_unselect_all (sel);
+
                if (priv->folder_to_select)
                        g_object_unref(priv->folder_to_select);
                priv->folder_to_select = TNY_FOLDER(g_object_ref(folder));
@@ -2147,12 +2180,19 @@ modest_folder_view_select_folder (ModestFolderView *self, TnyFolder *folder,
        if (!model)
                return FALSE;
 
-       sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
                
        gtk_tree_model_get_iter_first (model, &iter);
        if (find_folder_iter (model, &iter, &folder_iter, folder)) {
-               gtk_tree_selection_unselect_all (sel);
+               GtkTreePath *path;
+
+               path = gtk_tree_model_get_path (model, &folder_iter);
+               gtk_tree_view_expand_to_path (GTK_TREE_VIEW(self), path);
+
+               sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
                gtk_tree_selection_select_iter (sel, &folder_iter);
+               gtk_tree_view_set_cursor (GTK_TREE_VIEW(self), path, NULL, FALSE);
+
+               gtk_tree_path_free (path);
                return TRUE;
        }
        return FALSE;