* Removed a duplicated save_state call
[modest] / src / widgets / modest-folder-view.c
index 7fe6dd9..e28c3e2 100644 (file)
@@ -69,15 +69,16 @@ static void         modest_folder_view_set_account_store (TnyAccountStoreView *s
 
 static void         on_selection_changed   (GtkTreeSelection *sel, gpointer data);
 
-static void         on_account_update      (TnyAccountStore *account_store, 
-                                           const gchar *account,
+static void         on_account_removed     (TnyAccountStore *self, 
+                                           TnyAccount *account,
                                            gpointer user_data);
 
-static void         on_account_removed     (TnyAccountStore *self, 
+static void         on_account_inserted    (TnyAccountStore *self, 
                                            TnyAccount *account,
                                            gpointer user_data);
 
-static void         on_accounts_reloaded   (TnyAccountStore *store, 
+static void         on_account_changed    (TnyAccountStore *self, 
+                                           TnyAccount *account,
                                            gpointer user_data);
 
 static gint         cmp_rows               (GtkTreeModel *tree_model, 
@@ -93,10 +94,11 @@ static gboolean     on_key_pressed         (GtkWidget *self,
                                            GdkEventKey *event,
                                            gpointer user_data);
 
-static void         on_configuration_key_changed         (ModestConf* conf, 
-                                                         const gchar *key, 
-                                                         ModestConfEvent event, 
-                                                         ModestFolderView *self);
+static void         on_configuration_key_changed  (ModestConf* conf, 
+                                                  const gchar *key, 
+                                                  ModestConfEvent event,
+                                                  ModestConfNotificationId notification_id, 
+                                                  ModestFolderView *self);
 
 /* DnD functions */
 static void         on_drag_data_get       (GtkWidget *widget, 
@@ -122,6 +124,8 @@ static gboolean     on_drag_motion         (GtkWidget      *widget,
                                            guint           time,
                                            gpointer        user_data);
 
+static void         expand_root_items (ModestFolderView *self);
+
 static gint         expand_row_timeout     (gpointer data);
 
 static void         setup_drag_and_drop    (GtkTreeView *self);
@@ -131,7 +135,7 @@ static gboolean     _clipboard_set_selected_data (ModestFolderView *folder_view,
 
 static void         _clear_hidding_filter (ModestFolderView *folder_view);
 
-static void          on_row_changed_maybe_select_folder (GtkTreeModel     *tree_model, 
+static void         on_row_inserted_maybe_select_folder (GtkTreeModel     *tree_model, 
                                                         GtkTreePath      *path, 
                                                         GtkTreeIter      *iter,
                                                         ModestFolderView *self);
@@ -149,10 +153,12 @@ struct _ModestFolderViewPrivate {
 
        TnyFolder            *folder_to_select; /* folder to select after the next update */
 
-       gulong                account_update_signal;
+       ModestConfNotificationId notification_id;
+
        gulong                changed_signal;
-       gulong                accounts_reloaded_signal;
+       gulong                account_inserted_signal;
        gulong                account_removed_signal;
+       gulong                account_changed_signal;
        gulong                conf_key_signal;
        
        /* not unref this object, its a singlenton */
@@ -169,8 +175,8 @@ struct _ModestFolderViewPrivate {
        gchar                *visible_account_id;
        ModestFolderViewStyle style;
 
-       gboolean              reselect; /* we use this to force a reselection of the INBOX */
-       gboolean                                                        show_non_move;
+       gboolean  reselect; /* we use this to force a reselection of the INBOX */
+       gboolean  show_non_move;
 };
 #define MODEST_FOLDER_VIEW_GET_PRIVATE(o)                      \
        (G_TYPE_INSTANCE_GET_PRIVATE((o),                       \
@@ -258,7 +264,8 @@ modest_folder_view_class_init (ModestFolderViewClass *klass)
 }
 
 /* Simplify checks for NULLs: */
-static gboolean strings_are_equal (const gchar *a, const gchar *b)
+static gboolean
+strings_are_equal (const gchar *a, const gchar *b)
 {
        if (!a && !b)
                return TRUE;
@@ -270,7 +277,8 @@ static gboolean strings_are_equal (const gchar *a, const gchar *b)
                return FALSE;
 }
 
-static gboolean on_model_foreach_set_name(GtkTreeModel *model, GtkTreePath *path,  GtkTreeIter *iter, gpointer data)
+static gboolean
+on_model_foreach_set_name(GtkTreeModel *model, GtkTreePath *path,  GtkTreeIter *iter, gpointer data)
 {
        GObject *instance = NULL;
        
@@ -314,7 +322,8 @@ typedef struct
        gchar *previous_name;
 } GetMmcAccountNameData;
 
-static void on_get_mmc_account_name (TnyStoreAccount* account, gpointer user_data)
+static void
+on_get_mmc_account_name (TnyStoreAccount* account, gpointer user_data)
 {
        /* printf ("DEBU1G: %s: account name=%s\n", __FUNCTION__, tny_account_get_name (TNY_ACCOUNT(account))); */
 
@@ -347,9 +356,10 @@ text_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
        gint all = 0;
        TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
        GObject *instance = NULL;
-       
+
        g_return_if_fail (column);
        g_return_if_fail (tree_model);
+       g_return_if_fail (iter != NULL);
 
        gtk_tree_model_get (tree_model, iter,
                            TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &fname,
@@ -413,8 +423,7 @@ text_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
                         * added to the model, not when the account is 
                         * changed later, so get the name from the account
                         * instance: */
-                       item_name = g_strdup (tny_account_get_name (
-                               TNY_ACCOUNT (instance)));
+                       item_name = g_strdup (tny_account_get_name (TNY_ACCOUNT (instance)));
                        item_weight = 800;
                } else {
                        item_name = g_strdup (fname);
@@ -455,7 +464,7 @@ text_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
                        callback_data->previous_name = g_strdup (name); 
 
                modest_tny_account_get_mmc_account_name (TNY_STORE_ACCOUNT (instance), 
-                       on_get_mmc_account_name, callback_data);
+                                                        on_get_mmc_account_name, callback_data);
        }
                        
        g_object_unref (G_OBJECT (instance));
@@ -471,7 +480,7 @@ icon_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
        TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
        const gchar *account_id = NULL;
        gboolean has_children;
-       
+
        rendobj = G_OBJECT(renderer);
        gtk_tree_model_get (tree_model, iter,
                            TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
@@ -652,10 +661,12 @@ modest_folder_view_init (ModestFolderView *obj)
         * Track changes in the local account name (in the device it
         * will be the device name)
         */
-       priv->conf_key_signal = 
-               g_signal_connect (G_OBJECT(conf), 
-                                 "key_changed",
-                                 G_CALLBACK(on_configuration_key_changed), obj);
+       priv->notification_id = modest_conf_listen_to_namespace (conf, 
+                                                                MODEST_CONF_NAMESPACE);
+       priv->conf_key_signal = g_signal_connect (G_OBJECT(conf), 
+                                                 "key_changed",
+                                                 G_CALLBACK(on_configuration_key_changed), 
+                                                 obj);
 }
 
 static void
@@ -678,6 +689,12 @@ modest_folder_view_finalize (GObject *obj)
        
        priv =  MODEST_FOLDER_VIEW_GET_PRIVATE(obj);
 
+       if (priv->notification_id) {
+               modest_conf_forget_namespace (modest_runtime_get_conf (),
+                                             MODEST_CONF_NAMESPACE,
+                                             priv->notification_id);
+       }
+
        if (priv->timer_expander != 0) {
                g_source_remove (priv->timer_expander);
                priv->timer_expander = 0;
@@ -685,11 +702,11 @@ modest_folder_view_finalize (GObject *obj)
 
        if (priv->account_store) {
                g_signal_handler_disconnect (G_OBJECT(priv->account_store),
-                                            priv->account_update_signal);
-               g_signal_handler_disconnect (G_OBJECT(priv->account_store),
-                                            priv->accounts_reloaded_signal);
+                                            priv->account_inserted_signal);
                g_signal_handler_disconnect (G_OBJECT(priv->account_store),
                                             priv->account_removed_signal);
+               g_signal_handler_disconnect (G_OBJECT(priv->account_store),
+                                            priv->account_changed_signal);
                g_object_unref (G_OBJECT(priv->account_store));
                priv->account_store = NULL;
        }
@@ -699,6 +716,7 @@ modest_folder_view_finalize (GObject *obj)
                priv->query = NULL;
        }
 
+/*     modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(obj)); */
        if (priv->folder_to_select) {
                g_object_unref (G_OBJECT(priv->folder_to_select));
                priv->folder_to_select = NULL;
@@ -747,101 +765,177 @@ modest_folder_view_set_account_store (TnyAccountStoreView *self, TnyAccountStore
 
        if (G_UNLIKELY (priv->account_store)) {
 
-               if (g_signal_handler_is_connected (G_OBJECT (priv->account_store), 
-                                                  priv->account_update_signal))
-                       g_signal_handler_disconnect (G_OBJECT (priv->account_store), 
-                                                    priv->account_update_signal);
-               if (g_signal_handler_is_connected (G_OBJECT (priv->account_store), 
-                                                  priv->accounts_reloaded_signal))
-                       g_signal_handler_disconnect (G_OBJECT (priv->account_store), 
-                                                    priv->accounts_reloaded_signal);
+               if (g_signal_handler_is_connected (G_OBJECT (priv->account_store),
+                                                  priv->account_inserted_signal))
+                       g_signal_handler_disconnect (G_OBJECT (priv->account_store),
+                                                    priv->account_inserted_signal);
                if (g_signal_handler_is_connected (G_OBJECT (priv->account_store), 
                                                   priv->account_removed_signal))
                        g_signal_handler_disconnect (G_OBJECT (priv->account_store), 
                                                     priv->account_removed_signal);
-
+               if (g_signal_handler_is_connected (G_OBJECT (priv->account_store), 
+                                                  priv->account_changed_signal))
+                       g_signal_handler_disconnect (G_OBJECT (priv->account_store), 
+                                                    priv->account_changed_signal);
                g_object_unref (G_OBJECT (priv->account_store));
        }
 
        priv->account_store = g_object_ref (G_OBJECT (account_store));
 
-       priv->account_update_signal = 
-               g_signal_connect (G_OBJECT(account_store), "account_update",
-                                 G_CALLBACK (on_account_update), self);
-
        priv->account_removed_signal = 
                g_signal_connect (G_OBJECT(account_store), "account_removed",
                                  G_CALLBACK (on_account_removed), self);
 
-       priv->accounts_reloaded_signal = 
-               g_signal_connect (G_OBJECT(account_store), "accounts_reloaded",
-                                 G_CALLBACK (on_accounts_reloaded), self);
+       priv->account_inserted_signal =
+               g_signal_connect (G_OBJECT(account_store), "account_inserted",
+                                 G_CALLBACK (on_account_inserted), self);
 
-       g_signal_connect (G_OBJECT(account_store), "connecting_finished",
-                               G_CALLBACK (on_accounts_reloaded), self);
+       priv->account_changed_signal =
+               g_signal_connect (G_OBJECT(account_store), "account_changed",
+                                 G_CALLBACK (on_account_changed), self);
 
-       on_accounts_reloaded (account_store, (gpointer ) self);
+       modest_folder_view_update_model (MODEST_FOLDER_VIEW (self), account_store);
        
        g_object_unref (G_OBJECT (device));
 }
 
 static void
-on_account_removed (TnyAccountStore *account_store, 
-                   TnyAccount *account,
+on_account_inserted (TnyAccountStore *account_store, 
+                    TnyAccount *account,
+                    gpointer user_data)
+{
+       ModestFolderViewPrivate *priv;
+       GtkTreeModel *sort_model, *filter_model;
+
+       /* Ignore transport account insertions, we're not showing them
+          in the folder view */
+       if (TNY_IS_TRANSPORT_ACCOUNT (account))
+               return;
+
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (user_data);
+
+       /* 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 (user_data),
+                                             MODEST_CONF_FOLDER_VIEW_KEY);
+
+       /* Get the inner model */
+       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
+       sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
+
+       /* Insert the account in the model */
+       tny_list_append (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
+                        G_OBJECT (account));
+}
+
+
+static void
+on_account_changed (TnyAccountStore *account_store, 
+                   TnyAccount *tny_account,
                    gpointer user_data)
 {
-       ModestFolderView *self = MODEST_FOLDER_VIEW (user_data);
+       /* do nothing */
        ModestFolderViewPrivate *priv;
+       GtkTreeModel *sort_model, *filter_model;
 
-       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+       /* Ignore transport account insertions, we're not showing them
+          in the folder view */
+       if (TNY_IS_TRANSPORT_ACCOUNT (tny_account))
+               return;
 
-       /* If the removed account is the currently viewed one then
-          clear the configuration value. The new visible account will be the default account */
-       if (priv->visible_account_id &&
-           !strcmp (priv->visible_account_id, tny_account_get_id (account))) {
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (user_data);
 
-               /* Clear the current visible account_id */
-               modest_folder_view_set_account_id_of_visible_server_account (self, NULL);
+       /* Get the inner model */
+       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
+       sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
 
-               /* 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);
+       /* Remove the account from the model */
+       tny_list_remove (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
+                        G_OBJECT (tny_account));
 
-               /* Select the INBOX */
-               modest_folder_view_select_first_inbox_or_local (self);
-       }
+       /* Insert the account in the model */
+       tny_list_append (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
+                        G_OBJECT (tny_account));
 }
 
+
+
 static void
-on_account_update (TnyAccountStore *account_store, 
-                  const gchar *account,
-                  gpointer user_data)
+on_account_removed (TnyAccountStore *account_store, 
+                   TnyAccount *account,
+                   gpointer user_data)
 {
        ModestFolderView *self = NULL;
        ModestFolderViewPrivate *priv;
+       GtkTreeModel *sort_model, *filter_model;
+       GtkTreeSelection *sel = NULL;
+
+       /* Ignore transport account removals, we're not showing them
+          in the folder view */
+       if (TNY_IS_TRANSPORT_ACCOUNT (account))
+               return;
 
-       g_return_if_fail (MODEST_IS_FOLDER_VIEW (user_data));
        self = MODEST_FOLDER_VIEW (user_data);
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
 
-       /* 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)
+       /* Invalidate the cur_folder_store only if the selected folder
+          belongs to the account that is being removed */
+       if (priv->cur_folder_store) {
+               TnyAccount *selected_folder_account = NULL;
+
+               if (TNY_IS_FOLDER (priv->cur_folder_store)) {
+                       selected_folder_account = 
+                               tny_folder_get_account (TNY_FOLDER (priv->cur_folder_store));
+               } else {
+                       selected_folder_account = 
+                               TNY_ACCOUNT (g_object_ref (priv->cur_folder_store));
+               }
+
+               if (selected_folder_account == account) {
+                       sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+                       gtk_tree_selection_unselect_all (sel);
+               }
+               g_object_unref (selected_folder_account);
+       }
+
+       /* Invalidate row to select only if the folder to select
+          belongs to the account that is being removed*/
+       if (priv->folder_to_select) {
+               TnyAccount *folder_to_select_account = NULL;
+
+               folder_to_select_account = tny_folder_get_account (priv->folder_to_select);
+               if (folder_to_select_account == account) {
+/*                     modest_folder_view_disable_next_folder_selection (self); */
+                       g_object_unref (priv->folder_to_select);
+                       priv->folder_to_select = NULL;
+               }
+               g_object_unref (folder_to_select_account);
+       }
+
+       /* Remove the account from the model */
+       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+       sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
+       tny_list_remove (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
+                        G_OBJECT (account));
+
+       /* If the removed account is the currently viewed one then
+          clear the configuration value. The new visible account will be the default 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);
+       }
 
-       if (!modest_folder_view_update_model (self, account_store))
-               g_printerr ("modest: failed to update model for changes in '%s'",
-                           account);
-}
-
-static void 
-on_accounts_reloaded   (TnyAccountStore *account_store, 
-                       gpointer user_data)
-{
-       g_return_if_fail (MODEST_IS_FOLDER_VIEW (user_data));
-       modest_folder_view_update_model (MODEST_FOLDER_VIEW (user_data), account_store);
+       /* Select the INBOX */
+       modest_folder_view_select_first_inbox_or_local (self);
 }
 
 void
@@ -888,6 +982,9 @@ modest_folder_view_on_map (ModestFolderView *self,
                               signals[FOLDER_DISPLAY_NAME_CHANGED_SIGNAL], 0,
                               NULL);
        }
+
+       expand_root_items (self); 
+
        return FALSE;
 }
 
@@ -1061,7 +1158,7 @@ modest_folder_view_update_model (ModestFolderView *self,
        /* FIXME: the local accounts are not shown when the query
           selects only the subscribed folders. */
 /*     model        = tny_gtk_folder_store_tree_model_new (TRUE, priv->query); */
-       model        = tny_gtk_folder_store_tree_model_new (TRUE, NULL);
+       model        = tny_gtk_folder_store_tree_model_new (NULL);
        
        /* Deal with the model via its TnyList Interface,
         * filling the TnyList via a get_accounts() call: */
@@ -1093,16 +1190,14 @@ modest_folder_view_update_model (ModestFolderView *self,
 
        /* Set new model */
        gtk_tree_view_set_model (GTK_TREE_VIEW(self), filter_model);
-       g_signal_connect (G_OBJECT(filter_model), "row-changed",
-                         (GCallback)on_row_changed_maybe_select_folder, self);
        g_signal_connect (G_OBJECT(filter_model), "row-inserted",
-                         (GCallback)on_row_changed_maybe_select_folder, self);
+                         (GCallback) on_row_inserted_maybe_select_folder, self);
 
 
        g_object_unref (model);
        g_object_unref (filter_model);          
        g_object_unref (sortable);
-
+       
        /* Force a reselection of the INBOX next time the widget is shown */
        priv->reselect = TRUE;
                        
@@ -1113,19 +1208,19 @@ modest_folder_view_update_model (ModestFolderView *self,
 static void
 on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
 {
-       GtkTreeModel            *model;
-       TnyFolderStore          *folder = NULL;
-       GtkTreeIter             iter;
-       ModestFolderView        *tree_view;
-       ModestFolderViewPrivate *priv;
+       GtkTreeModel *model = NULL;
+       TnyFolderStore *folder = NULL;
+       GtkTreeIter iter;
+       ModestFolderView *tree_view = NULL;
+       ModestFolderViewPrivate *priv = NULL;
+       gboolean selected = FALSE;
 
        g_return_if_fail (sel);
        g_return_if_fail (user_data);
        
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE(user_data);
 
-       if(!gtk_tree_selection_get_selected (sel, &model, &iter))
-               return;
+       selected = gtk_tree_selection_get_selected (sel, &model, &iter);
 
        /* Notify the display name observers */
        g_signal_emit (G_OBJECT(user_data),
@@ -1133,14 +1228,17 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
                       NULL);
 
        tree_view = MODEST_FOLDER_VIEW (user_data);
-       gtk_tree_model_get (model, &iter,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &folder,
-                           -1);
 
-       /* If the folder is the same do not notify */
-       if (priv->cur_folder_store == folder && folder) {
-               g_object_unref (folder);
-               return;
+       if (selected) {
+               gtk_tree_model_get (model, &iter,
+                                   TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &folder,
+                                   -1);
+
+               /* If the folder is the same do not notify */
+               if (priv->cur_folder_store == folder && folder) {
+                       g_object_unref (folder);
+                       return;
+               }
        }
        
        /* Current folder was unselected */
@@ -1151,6 +1249,7 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
                if (TNY_IS_FOLDER(priv->cur_folder_store))
                        tny_folder_sync_async (TNY_FOLDER(priv->cur_folder_store),
                                               FALSE, NULL, NULL, NULL);
+
                /* FALSE --> don't expunge the messages */
 
                g_object_unref (priv->cur_folder_store);
@@ -1422,7 +1521,7 @@ on_progress_changed (ModestMailOperation *mail_op,
        gtk_drag_finish (helper->context, success, FALSE, helper->time);
 
        /* Free the helper */
-       gtk_tree_path_free (helper->source_row);        
+       gtk_tree_path_free (helper->source_row);
        g_slice_free (DndHelper, helper);
 }
 
@@ -1442,6 +1541,18 @@ tree_path_to_folder (GtkTreeModel *model, GtkTreePath *path)
        return folder;
 }
 
+static void 
+show_banner_move_target_error ()
+{
+       ModestWindow *main_window;
+
+       main_window = modest_window_mgr_get_main_window(
+                       modest_runtime_get_window_mgr());
+                               
+       modest_platform_information_banner(GTK_WIDGET(main_window),
+                       NULL, _("mail_in_ui_folder_move_target_error"));
+}
+
 /*
  * This function is used by drag_data_received_cb to manage drag and
  * drop of a header, i.e, and drag from the header view to the folder
@@ -1458,6 +1569,8 @@ drag_and_drop_from_header_view (GtkTreeModel *source_model,
        TnyFolder *folder = NULL;
        ModestMailOperation *mail_op = NULL;
        GtkTreeIter source_iter;
+       ModestWindowMgr *mgr = NULL; /*no need for unref*/
+       ModestWindow *main_win = NULL; /*no need for unref*/
 
        g_return_if_fail (GTK_IS_TREE_MODEL(source_model));
        g_return_if_fail (GTK_IS_TREE_MODEL(dest_model));
@@ -1474,10 +1587,17 @@ drag_and_drop_from_header_view (GtkTreeModel *source_model,
                goto cleanup;
        }
        
+       /* Check if the selected message is in msg-view. If it is than
+        * do not enable drag&drop on that. */
+       mgr = modest_runtime_get_window_mgr ();
+       if (modest_window_mgr_find_registered_header(mgr, header, NULL))
+               goto cleanup;
+
        /* Get Folder */
        folder = tree_path_to_folder (dest_model, dest_row);
        if (!TNY_IS_FOLDER(folder)) {
                g_warning ("BUG: %s could not get a valid folder", __FUNCTION__);
+               show_banner_move_target_error();
                goto cleanup;
        }
        if (modest_tny_folder_get_rules(folder) & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
@@ -1485,6 +1605,13 @@ drag_and_drop_from_header_view (GtkTreeModel *source_model,
                goto cleanup;
        }
        
+       headers = tny_simple_list_new ();
+       tny_list_append (headers, G_OBJECT (header));
+
+       main_win = modest_window_mgr_get_main_window(mgr);
+       if(msgs_move_to_confirmation(GTK_WINDOW(main_win), folder, TRUE, headers)
+                       == GTK_RESPONSE_CANCEL)
+               goto cleanup;
 
        /* Transfer message */
        mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, 
@@ -1496,8 +1623,6 @@ drag_and_drop_from_header_view (GtkTreeModel *source_model,
        g_signal_connect (G_OBJECT (mail_op), "progress-changed",
                          G_CALLBACK (on_progress_changed), helper);
 
-       headers = tny_simple_list_new ();
-       tny_list_append (headers, G_OBJECT (header));
        modest_mail_operation_xfer_msgs (mail_op, 
                                         headers, 
                                         folder, 
@@ -1529,39 +1654,46 @@ drag_and_drop_from_folder_view (GtkTreeModel     *source_model,
                                DndHelper        *helper)
 {
        ModestMailOperation *mail_op = NULL;
-       GtkTreeIter parent_iter, iter;
-       TnyFolderStore *parent_folder = NULL;
+       GtkTreeIter dest_iter, iter;
+       TnyFolderStore *dest_folder = NULL;
        TnyFolder *folder = NULL;
-       gboolean forbidden = TRUE;
+       gboolean forbidden = FALSE;
 
-       /* check the folder rules for the destination */
-       folder = tree_path_to_folder (dest_model, dest_row);
-       if (folder) {
-               ModestTnyFolderRules rules =
-                       modest_tny_folder_get_rules (folder);
-               forbidden = rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE;
-               if (forbidden)
-                       g_debug ("folder rules: cannot write to that folder");
+       if (!forbidden) {
+               /* check the folder rules for the destination */
+               folder = tree_path_to_folder (dest_model, dest_row);
+               if (TNY_IS_FOLDER(folder)) {
+                       ModestTnyFolderRules rules =
+                                       modest_tny_folder_get_rules (folder);
+                       forbidden = rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE;
+
+                       if (forbidden)
+                               g_debug ("folder rules: cannot write to that folder");
+               } else if (TNY_IS_FOLDER_STORE(folder)){
+                       /* enable local root as destination for folders */
+                       if (!MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder)
+                                       && TNY_IS_ACCOUNT (folder))
+                               forbidden = TRUE;
+               }
                g_object_unref (folder);
        }
-       
        if (!forbidden) {
                /* check the folder rules for the source */
                folder = tree_path_to_folder (source_model, helper->source_row);
-               if (folder) {
+               if (TNY_IS_FOLDER(folder)) {
                        ModestTnyFolderRules rules =
-                               modest_tny_folder_get_rules (folder);
+                                       modest_tny_folder_get_rules (folder);
                        forbidden = rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE;
                        if (forbidden)
                                g_debug ("folder rules: cannot move that folder");
-                       g_object_unref (folder);
-               }
+               } else
+                       forbidden = TRUE;
+               g_object_unref (folder);
        }
 
        
        /* Check if the drag is possible */
        if (forbidden || !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);        
                g_slice_free (DndHelper, helper);
@@ -1569,40 +1701,47 @@ drag_and_drop_from_folder_view (GtkTreeModel     *source_model,
        }
 
        /* Get data */
-       gtk_tree_model_get_iter (source_model, &parent_iter, dest_row);
-       gtk_tree_model_get_iter (source_model, &iter, helper->source_row);
-       gtk_tree_model_get (source_model, &parent_iter, 
+       gtk_tree_model_get_iter (dest_model, &dest_iter, dest_row);
+       gtk_tree_model_get (dest_model, &dest_iter, 
                            TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, 
-                           &parent_folder, -1);
+                           &dest_folder, -1);
+       gtk_tree_model_get_iter (source_model, &iter, helper->source_row);
        gtk_tree_model_get (source_model, &iter,
                            TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
                            &folder, -1);
 
        /* 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))) {
+       if (modest_platform_connect_and_wait_if_network_folderstore (
+                               NULL, dest_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 (), 
-                                        mail_op);
-               g_signal_connect (G_OBJECT (mail_op), "progress-changed",
-                                 G_CALLBACK (on_progress_changed), helper);
+               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",
+                               G_CALLBACK (on_progress_changed),
+                               helper);
 
                modest_mail_operation_xfer_folder (mail_op, 
-                                          folder, 
-                                          parent_folder,
-                                          helper->delete_source,
-                                          NULL,
-                                          NULL);
+                               folder, 
+                               dest_folder,
+                               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 (dest_folder));
        g_object_unref (G_OBJECT (folder));
 }
 
@@ -1949,17 +2088,20 @@ on_key_pressed (GtkWidget *self,
 static void 
 on_configuration_key_changed (ModestConf* conf, 
                              const gchar *key, 
-                             ModestConfEvent event, 
+                             ModestConfEvent event,
+                             ModestConfNotificationId id, 
                              ModestFolderView *self)
 {
        ModestFolderViewPrivate *priv;
 
-       if (!key)
-               return;
 
        g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self);
 
+       /* Do not listen for changes in other namespaces */
+       if (priv->notification_id != id)
+                return;
+        
        if (!strcmp (key, MODEST_CONF_DEVICE_NAME)) {
                g_free (priv->local_account_name);
 
@@ -1978,7 +2120,7 @@ on_configuration_key_changed (ModestConf* conf,
        }
 }
 
-void 
+void
 modest_folder_view_set_style (ModestFolderView *self,
                              ModestFolderViewStyle style)
 {
@@ -2091,6 +2233,9 @@ modest_folder_view_select_first_inbox_or_local (ModestFolderView *self)
        /* Select the row and free */
        gtk_tree_view_set_cursor (GTK_TREE_VIEW (self), path, NULL, FALSE);
        gtk_tree_path_free (path);
+
+       /* set focus */
+       gtk_widget_grab_focus (GTK_WIDGET(self));
 }
 
 
@@ -2110,8 +2255,6 @@ find_folder_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *folder_it
                                    TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &name,
                                    TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type, 
                                    -1);                
-       
-               g_debug ("===> %s (%p ---- %p)", name, a_folder, folder);
                g_free (name);
 
                if (folder == a_folder) {
@@ -2133,8 +2276,8 @@ find_folder_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *folder_it
 
 
 static void
-on_row_changed_maybe_select_folder (GtkTreeModel *tree_model, GtkTreePath  *path, GtkTreeIter *iter,
-                                   ModestFolderView *self)
+on_row_inserted_maybe_select_folder (GtkTreeModel *tree_model, GtkTreePath  *path, GtkTreeIter *iter,
+                                    ModestFolderView *self)
 {
        ModestFolderViewPrivate *priv = NULL;
        GtkTreeSelection *sel;
@@ -2160,12 +2303,29 @@ on_row_changed_maybe_select_folder (GtkTreeModel *tree_model, GtkTreePath  *path
                        gtk_tree_path_free (path);
                
                }
-               g_object_unref (priv->folder_to_select);
-               priv->folder_to_select = NULL;
+
+               /* Disable next */
+               modest_folder_view_disable_next_folder_selection (self);
+/*             g_object_unref (priv->folder_to_select); */
+/*             priv->folder_to_select = NULL; */
        }
 }
 
 
+void
+modest_folder_view_disable_next_folder_selection (ModestFolderView *self) 
+{
+       ModestFolderViewPrivate *priv = NULL;
+
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));        
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       if (priv->folder_to_select)
+               g_object_unref(priv->folder_to_select);
+       
+       priv->folder_to_select = NULL;
+}
+
 gboolean
 modest_folder_view_select_folder (ModestFolderView *self, TnyFolder *folder, 
                                  gboolean after_change)
@@ -2254,13 +2414,48 @@ modest_folder_view_cut_selection (ModestFolderView *folder_view)
 }
 
 void
+modest_folder_view_copy_model (ModestFolderView *folder_view_src,
+                              ModestFolderView *folder_view_dst)
+{
+       GtkTreeModel *filter_model = NULL;
+       GtkTreeModel *model = NULL;
+       GtkTreeModel *new_filter_model = NULL;
+       
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (folder_view_src));
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (folder_view_dst));
+
+       /* Get src model*/
+       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view_src));
+       model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER(filter_model));
+
+       /* Build new filter model */
+       new_filter_model = gtk_tree_model_filter_new (model, NULL);     
+       gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (new_filter_model),
+                                               filter_row,
+                                               folder_view_dst,
+                                               NULL);
+       /* Set copied model */
+       gtk_tree_view_set_model (GTK_TREE_VIEW (folder_view_dst), new_filter_model);
+
+       /* Free */
+       g_object_unref (new_filter_model);
+}
+
+void
 modest_folder_view_show_non_move_folders (ModestFolderView *folder_view,
-                                   gboolean show)
+                                         gboolean show)
 {
+       GtkTreeModel *model = NULL;
        ModestFolderViewPrivate* priv = MODEST_FOLDER_VIEW_GET_PRIVATE(folder_view);
        priv->show_non_move = show;
-       modest_folder_view_update_model(folder_view,
-                                                                                                                                       TNY_ACCOUNT_STORE(modest_runtime_get_account_store()));
+/*     modest_folder_view_update_model(folder_view, */
+/*                                     TNY_ACCOUNT_STORE(modest_runtime_get_account_store())); */
+
+       /* Hide special folders */
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view));
+       if (GTK_IS_TREE_MODEL_FILTER (model)) {
+               gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model));
+       }
 }
 
 /* Returns FALSE if it did not selected anything */