Fix modest_utils_show_dialog_and_forget for gtk and modest shell
[modest] / src / widgets / modest-folder-view.c
index 8a2ab7f..637675b 100644 (file)
 #include <gdk/gdkkeysyms.h>
 #include <tny-account-store-view.h>
 #include <tny-gtk-account-list-model.h>
-#ifdef MODEST_TOOLKIT_HILDON2
 #include <tny-gtk-folder-list-store.h>
-#else
 #include <tny-gtk-folder-store-tree-model.h>
-#endif
 #include <tny-gtk-header-list-model.h>
 #include <tny-merge-folder.h>
 #include <tny-folder.h>
@@ -47,6 +44,7 @@
 #include <tny-camel-folder.h>
 #include <tny-simple-list.h>
 #include <tny-camel-account.h>
+#include <modest-defs.h>
 #include <modest-tny-account.h>
 #include <modest-tny-folder.h>
 #include <modest-tny-local-folders-account.h>
@@ -64,6 +62,7 @@
 #include "modest-dnd.h"
 #include "modest-ui-constants.h"
 #include "widgets/modest-window.h"
+#include <modest-account-protocol.h>
 
 /* Folder view drag types */
 const GtkTargetEntry folder_view_drag_types[] =
@@ -73,31 +72,20 @@ const GtkTargetEntry folder_view_drag_types[] =
 };
 
 /* Default icon sizes for Fremantle style are different */
-#ifdef MODEST_TOOLKIT_HILDON2
 #define FOLDER_ICON_SIZE MODEST_ICON_SIZE_BIG
-#else
-#define FOLDER_ICON_SIZE MODEST_ICON_SIZE_SMALL
-#endif
 
 /* Column names depending on we use list store or tree store */
-#ifdef MODEST_TOOLKIT_HILDON2
 #define NAME_COLUMN TNY_GTK_FOLDER_LIST_STORE_NAME_COLUMN
 #define UNREAD_COLUMN TNY_GTK_FOLDER_LIST_STORE_UNREAD_COLUMN
 #define ALL_COLUMN TNY_GTK_FOLDER_LIST_STORE_ALL_COLUMN
 #define TYPE_COLUMN TNY_GTK_FOLDER_LIST_STORE_TYPE_COLUMN
 #define INSTANCE_COLUMN TNY_GTK_FOLDER_LIST_STORE_INSTANCE_COLUMN
-#else
-#define NAME_COLUMN TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN
-#define UNREAD_COLUMN TNY_GTK_FOLDER_STORE_TREE_MODEL_UNREAD_COLUMN
-#define ALL_COLUMN TNY_GTK_FOLDER_STORE_TREE_MODEL_ALL_COLUMN
-#define TYPE_COLUMN TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN
-#define INSTANCE_COLUMN TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN
-#endif
 
 /* 'private'/'protected' functions */
 static void modest_folder_view_class_init  (ModestFolderViewClass *klass);
 static void modest_folder_view_init        (ModestFolderView *obj);
 static void modest_folder_view_finalize    (GObject *obj);
+static void modest_folder_view_dispose     (GObject *obj);
 
 static void         tny_account_store_view_init (gpointer g,
                                                 gpointer iface_data);
@@ -144,59 +132,35 @@ static void         on_configuration_key_changed  (ModestConf* conf,
                                                   ModestConfNotificationId notification_id,
                                                   ModestFolderView *self);
 
-/* DnD functions */
-static void         on_drag_data_get       (GtkWidget *widget,
-                                           GdkDragContext *context,
-                                           GtkSelectionData *selection_data,
-                                           guint info,
-                                           guint time,
-                                           gpointer data);
-
-static void         on_drag_data_received  (GtkWidget *widget,
-                                           GdkDragContext *context,
-                                           gint x,
-                                           gint y,
-                                           GtkSelectionData *selection_data,
-                                           guint info,
-                                           guint time,
-                                           gpointer data);
-
-static gboolean     on_drag_motion         (GtkWidget      *widget,
-                                           GdkDragContext *context,
-                                           gint            x,
-                                           gint            y,
-                                           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);
-
 static gboolean     _clipboard_set_selected_data (ModestFolderView *folder_view,
                                                  gboolean delete);
 
 static void         _clear_hidding_filter (ModestFolderView *folder_view);
 
-#ifndef MODEST_TOOLKIT_HILDON2
-static void         on_row_inserted_maybe_select_folder (GtkTreeModel     *tree_model,
-                                                        GtkTreePath      *path,
-                                                        GtkTreeIter      *iter,
-                                                        ModestFolderView *self);
-#endif
-
 static void         on_display_name_changed (ModestAccountMgr *self,
                                             const gchar *account,
                                             gpointer user_data);
 static void         update_style (ModestFolderView *self);
 static void         on_notify_style (GObject *obj, GParamSpec *spec, gpointer userdata);
 static gint         get_cmp_pos (TnyFolderType t, TnyFolder *folder_store);
+static gboolean     inbox_is_special (TnyFolderStore *folder_store);
+
+static gboolean     get_inner_models        (ModestFolderView *self,
+                                            GtkTreeModel **filter_model,
+                                            GtkTreeModel **sort_model,
+                                            GtkTreeModel **tny_model);
+static void on_activity_changed (TnyGtkFolderListStore *store,
+                                gboolean activity,
+                                ModestFolderView *folder_view);
 
 enum {
        FOLDER_SELECTION_CHANGED_SIGNAL,
        FOLDER_DISPLAY_NAME_CHANGED_SIGNAL,
        FOLDER_ACTIVATED_SIGNAL,
+       VISIBLE_ACCOUNT_CHANGED_SIGNAL,
+       ACTIVITY_CHANGED_SIGNAL,
        LAST_SIGNAL
 };
 
@@ -223,18 +187,27 @@ struct _ModestFolderViewPrivate {
        ModestFolderViewFilter filter;
 
        TnyFolderStoreQuery  *query;
+       gboolean              do_refresh;
        guint                 timer_expander;
 
        gchar                *local_account_name;
        gchar                *visible_account_id;
+       gchar                *mailbox;
        ModestFolderViewStyle style;
        ModestFolderViewCellStyle cell_style;
+       gboolean show_message_count;
 
        gboolean  reselect; /* we use this to force a reselection of the INBOX */
        gboolean  show_non_move;
+       TnyList   *list_to_move;
        gboolean  reexpand; /* next time we expose, we'll expand all root folders */
 
        GtkCellRenderer *messages_renderer;
+
+       gulong                outbox_deleted_handler;
+
+       GSList   *signal_handlers;
+       GdkColor active_color;
 };
 #define MODEST_FOLDER_VIEW_GET_PRIVATE(o)                      \
        (G_TYPE_INSTANCE_GET_PRIVATE((o),                       \
@@ -291,6 +264,7 @@ modest_folder_view_class_init (ModestFolderViewClass *klass)
 
        parent_class            = g_type_class_peek_parent (klass);
        gobject_class->finalize = modest_folder_view_finalize;
+       gobject_class->dispose  = modest_folder_view_dispose;
 
        g_type_class_add_private (gobject_class,
                                  sizeof(ModestFolderViewPrivate));
@@ -332,6 +306,32 @@ modest_folder_view_class_init (ModestFolderViewClass *klass)
                              g_cclosure_marshal_VOID__POINTER,
                              G_TYPE_NONE, 1, G_TYPE_POINTER);
 
+       /*
+        * Emitted whenever the visible account changes
+        */
+       signals[VISIBLE_ACCOUNT_CHANGED_SIGNAL] =
+               g_signal_new ("visible-account-changed",
+                             G_TYPE_FROM_CLASS (gobject_class),
+                             G_SIGNAL_RUN_FIRST,
+                             G_STRUCT_OFFSET (ModestFolderViewClass,
+                                              visible_account_changed),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__STRING,
+                             G_TYPE_NONE, 1, G_TYPE_STRING);
+
+       /*
+        * Emitted when the underlying GtkListStore is updating data
+        */
+       signals[ACTIVITY_CHANGED_SIGNAL] =
+               g_signal_new ("activity-changed",
+                             G_TYPE_FROM_CLASS (gobject_class),
+                             G_SIGNAL_RUN_FIRST,
+                             G_STRUCT_OFFSET (ModestFolderViewClass,
+                                              activity_changed),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__BOOLEAN,
+                             G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
        treeview_class->select_cursor_parent = NULL;
 
 #ifdef MODEST_TOOLKIT_HILDON2
@@ -341,6 +341,41 @@ modest_folder_view_class_init (ModestFolderViewClass *klass)
 
 }
 
+/* Retrieves the filter, sort and tny models of the folder view. If
+   any of these does not exist then it returns FALSE */
+static gboolean
+get_inner_models (ModestFolderView *self, 
+                 GtkTreeModel **filter_model,
+                 GtkTreeModel **sort_model,
+                 GtkTreeModel **tny_model)
+{
+       GtkTreeModel *s_model, *f_model, *t_model;
+
+       f_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+       if (!GTK_IS_TREE_MODEL_FILTER(f_model)) {
+               g_debug ("%s: emtpy model or not filter model", __FUNCTION__);
+               return FALSE;
+       }
+
+       s_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (f_model));
+       if (!GTK_IS_TREE_MODEL_SORT(s_model)) {
+               g_warning ("BUG: %s: not a valid sort model", __FUNCTION__);
+               return FALSE;
+       }
+
+       t_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model));
+
+       /* Assign values */
+       if (filter_model)
+               *filter_model = f_model;
+       if (sort_model)
+               *sort_model = s_model;
+       if (tny_model)
+               *tny_model = t_model;
+
+       return TRUE;
+}
+
 /* Simplify checks for NULLs: */
 static gboolean
 strings_are_equal (const gchar *a, const gchar *b)
@@ -427,15 +462,28 @@ static void
 convert_parent_folders_to_dots (gchar **item_name)
 {
        gint n_parents = 0;
+       gint n_inbox_parents = 0;
        gchar *c;
+       gchar *path_start;
        gchar *last_separator;
 
        if (item_name == NULL)
                return;
 
+       path_start = *item_name;
        for (c = *item_name; *c != '\0'; c++) {
                if (g_str_has_prefix (c, MODEST_FOLDER_PATH_SEPARATOR)) {
+                       gchar *compare;
+                       if (c != path_start) {
+                               compare = g_strndup (path_start, c - path_start);
+                               compare = g_strstrip (compare);
+                               if (g_ascii_strcasecmp (compare, "inbox") == 0) {
+                                       n_inbox_parents++;
+                               }
+                               g_free (compare);
+                       }
                        n_parents++;
+                       path_start = c + 1;
                }
        }
 
@@ -449,7 +497,7 @@ convert_parent_folders_to_dots (gchar **item_name)
                gint i;
 
                buffer = g_string_new ("");
-               for (i = 0; i < n_parents; i++) {
+               for (i = 0; i < n_parents - n_inbox_parents; i++) {
                        buffer = g_string_append (buffer, MODEST_FOLDER_DOT);
                }
                buffer = g_string_append (buffer, last_separator);
@@ -460,8 +508,9 @@ convert_parent_folders_to_dots (gchar **item_name)
 }
 
 static void
-format_compact_style (gchar **item_name, 
+format_compact_style (gchar **item_name,
                      GObject *instance,
+                     const gchar *mailbox,
                      gboolean bold,
                      gboolean multiaccount,
                      gboolean *use_markup)
@@ -478,6 +527,16 @@ format_compact_style (gchar **item_name,
        folder_type = tny_folder_get_folder_type (folder);
        is_special = (get_cmp_pos (folder_type, folder)!= 4);
 
+       if (mailbox) {
+               /* Remove mailbox prefix if any */
+               gchar *prefix = g_strconcat (mailbox, MODEST_FOLDER_PATH_SEPARATOR, NULL);
+               if (g_str_has_prefix (*item_name, prefix)) {
+                       gchar *new_item_name = g_strdup (*item_name + strlen (prefix));
+                       g_free (*item_name);
+                       *item_name = new_item_name;
+               }
+       }
+
        if (!is_special || multiaccount) {
                TnyAccount *account = tny_folder_get_account (folder);
                const gchar *folder_name;
@@ -502,15 +561,20 @@ format_compact_style (gchar **item_name,
 
                buffer = g_string_append (buffer, *item_name);
                if (concat_folder_name) {
-                       if (bold) buffer = g_string_append (buffer, "<span weight='bold'>");
-                       buffer = g_string_append (buffer, folder_name);
-                       if (bold) buffer = g_string_append (buffer, "</span>");
+                       if (!is_special && folder_type == TNY_FOLDER_TYPE_DRAFTS) {
+                               buffer = g_string_append (buffer, folder_name);
+                               /* TODO: append a sensitive string to the remote drafts to
+                                * be able to know it's the remote one */
+/*                             buffer = g_string_append (buffer, " (TODO:remote)"); */
+                       } else {
+                               buffer = g_string_append (buffer, folder_name);
+                       }
                }
                g_free (*item_name);
                g_object_unref (account);
 
                *item_name = g_string_free (buffer, FALSE);
-               *use_markup = bold;
+               *use_markup = FALSE;
        } else {
                *use_markup = FALSE;
        }
@@ -547,9 +611,12 @@ text_cell_data  (GtkTreeViewColumn *column,
        if (type != TNY_FOLDER_TYPE_ROOT) {
                gint number = 0;
                gboolean drafts;
+               gboolean is_local;
 
-               if (modest_tny_folder_is_local_folder (TNY_FOLDER (instance)) ||
-                   modest_tny_folder_is_memory_card_folder (TNY_FOLDER (instance))) {
+               is_local = modest_tny_folder_is_local_folder (TNY_FOLDER (instance)) ||
+                       modest_tny_folder_is_memory_card_folder (TNY_FOLDER (instance));
+
+               if (is_local) {
                        type = modest_tny_folder_get_local_or_mmc_folder_type (TNY_FOLDER (instance));
                        if (type != TNY_FOLDER_TYPE_UNKNOWN) {
                                g_free (fname);
@@ -564,18 +631,14 @@ text_cell_data  (GtkTreeViewColumn *column,
                        }
                }
 
-               if (type == TNY_FOLDER_TYPE_INBOX) {
-                       g_free (fname);
-                       fname = g_strdup (_("mcen_me_folder_inbox"));
-               }
-
-               /* note: we cannot reliably get the counts from the tree model, we need
-                * to use explicit calls on tny_folder for some reason.
-                */
-               /* Select the number to show: the unread or unsent messages. in case of outbox/drafts, show all */
-               if ((type == TNY_FOLDER_TYPE_DRAFTS) ||
-                   (type == TNY_FOLDER_TYPE_OUTBOX) ||
-                   (type == TNY_FOLDER_TYPE_MERGE)) { /* _OUTBOX actually returns _MERGE... */
+               /* note: we cannot reliably get the counts from the
+                * tree model, we need to use explicit calls on
+                * tny_folder for some reason. Select the number to
+                * show: the unread or unsent messages. in case of
+                * outbox/drafts, show all */
+               if (is_local && ((type == TNY_FOLDER_TYPE_DRAFTS) ||
+                                (type == TNY_FOLDER_TYPE_OUTBOX) ||
+                                (type == TNY_FOLDER_TYPE_MERGE))) { /* _OUTBOX actually returns _MERGE... */
                        number = tny_folder_get_all_count (TNY_FOLDER(instance));
                        drafts = TRUE;
                } else {
@@ -593,7 +656,11 @@ text_cell_data  (GtkTreeViewColumn *column,
                } else {
                        /* Use bold font style if there are unread or unset messages */
                        if (number > 0) {
-                               item_name = g_strdup_printf ("%s (%d)", fname, number);
+                               if (priv->show_message_count) {
+                                       item_name = g_strdup_printf ("%s (%d)", fname, number);
+                               } else {
+                                       item_name = g_strdup (fname);
+                               }
                                item_weight = 800;
                        } else {
                                item_name = g_strdup (fname);
@@ -619,6 +686,13 @@ text_cell_data  (GtkTreeViewColumn *column,
                }
        }
 
+       /* Convert INBOX */
+       if (type == TNY_FOLDER_TYPE_INBOX &&
+           g_str_has_suffix (fname, "Inbox")) {
+               g_free (item_name);
+               item_name = g_strdup (_("mcen_me_folder_inbox"));
+       }
+
        if (!item_name)
                item_name = g_strdup ("unknown");
 
@@ -627,17 +701,29 @@ text_cell_data  (GtkTreeViewColumn *column,
 
                multiaccount = (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
                /* Convert item_name to markup */
-               format_compact_style (&item_name, instance, 
+               format_compact_style (&item_name, instance, priv->mailbox,
                                      item_weight == 800, 
                                      multiaccount, &use_markup);
        }
 
        if (item_name && item_weight) {
                /* Set the name in the treeview cell: */
-               if (use_markup)
-                       g_object_set (rendobj, "markup", item_name, NULL);
-               else
-                       g_object_set (rendobj, "text", item_name, "weight", item_weight, NULL);
+               if (priv->cell_style == MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT && item_weight == 800 && 
+                   (priv->active_color.red != 0 || priv->active_color.blue != 0 || priv->active_color.green != 0)) {
+                       g_object_set (rendobj, 
+                                     "text", item_name, 
+                                     "weight-set", FALSE,
+                                     "foreground-set", TRUE,
+                                     "foreground-gdk", &(priv->active_color),
+                                     NULL);
+               } else {
+                       g_object_set (rendobj, 
+                                     "text", item_name,
+                                     "foreground-set", FALSE,
+                                     "weight-set", TRUE, 
+                                     "weight", item_weight,
+                                     NULL);
+               }
 
                /* Notify display name observers */
                /* TODO: What listens for this signal, and how can it use only the new name? */
@@ -702,9 +788,12 @@ messages_cell_data  (GtkTreeViewColumn *column,
        if (type != TNY_FOLDER_TYPE_ROOT) {
                gint number = 0;
                gboolean drafts;
+               gboolean is_local;
+
+               is_local = modest_tny_folder_is_local_folder (TNY_FOLDER (instance)) ||
+                       modest_tny_folder_is_memory_card_folder (TNY_FOLDER (instance));
 
-               if (modest_tny_folder_is_local_folder (TNY_FOLDER (instance)) ||
-                   modest_tny_folder_is_memory_card_folder (TNY_FOLDER (instance))) {
+               if (is_local) {
                        type = modest_tny_folder_get_local_or_mmc_folder_type (TNY_FOLDER (instance));
                } else {
                        /* Sometimes an special folder is reported by the server as
@@ -719,9 +808,9 @@ messages_cell_data  (GtkTreeViewColumn *column,
                 * to use explicit calls on tny_folder for some reason.
                 */
                /* Select the number to show: the unread or unsent messages. in case of outbox/drafts, show all */
-               if ((type == TNY_FOLDER_TYPE_DRAFTS) ||
-                   (type == TNY_FOLDER_TYPE_OUTBOX) ||
-                   (type == TNY_FOLDER_TYPE_MERGE)) { /* _OUTBOX actually returns _MERGE... */
+               if (is_local && ((type == TNY_FOLDER_TYPE_DRAFTS) ||
+                                (type == TNY_FOLDER_TYPE_OUTBOX) ||
+                                (type == TNY_FOLDER_TYPE_MERGE))) { /* _OUTBOX actually returns _MERGE... */
                        number = tny_folder_get_all_count (TNY_FOLDER(instance));
                        drafts = TRUE;
                } else {
@@ -729,14 +818,13 @@ messages_cell_data  (GtkTreeViewColumn *column,
                        drafts = FALSE;
                }
 
-               if (priv->cell_style == MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT) {
-                       if (number > 0) {
-                               item_name = g_strdup_printf (drafts?_("mcen_ti_messages"):_("mcen_ti_new_messages"), 
-                                                            number);
-                       } 
-               } 
-
-       } 
+               if ((priv->cell_style == MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT) && (number > 0)) {
+                       item_name =
+                               g_strdup_printf (ngettext ((drafts) ? "mcen_ti_message" : "mcen_va_new_message",
+                                                          (drafts) ? "mcen_ti_messages" : "mcen_va_new_messages",
+                                                          number), number);
+               }
+       }
 
        if (!item_name)
                item_name = g_strdup ("");
@@ -791,53 +879,118 @@ get_composite_icons (const gchar *icon_code,
 {
        ThreePixbufs *retval;
 
-       if (!*pixbuf)
-               *pixbuf = gdk_pixbuf_copy (modest_platform_get_icon (icon_code, FOLDER_ICON_SIZE));
+       if (pixbuf && !*pixbuf) {
+               GdkPixbuf *icon;
+               icon = modest_platform_get_icon (icon_code, FOLDER_ICON_SIZE);
+               if (icon) {
+                       *pixbuf = gdk_pixbuf_copy (icon);
+               } else {
+                       *pixbuf = NULL;
+               }
+       }
 
-       if (!*pixbuf_open)
+       if (pixbuf_open && !*pixbuf_open && pixbuf && *pixbuf)
                *pixbuf_open = get_composite_pixbuf ("qgn_list_gene_fldr_exp",
                                                     FOLDER_ICON_SIZE,
                                                     *pixbuf);
 
-       if (!*pixbuf_close)
+       if (pixbuf_close && !*pixbuf_close && pixbuf && *pixbuf)
                *pixbuf_close = get_composite_pixbuf ("qgn_list_gene_fldr_clp",
                                                      FOLDER_ICON_SIZE,
                                                      *pixbuf);
 
        retval = g_slice_new0 (ThreePixbufs);
-       if (*pixbuf)
+       if (pixbuf && *pixbuf)
                retval->pixbuf = g_object_ref (*pixbuf);
-       if (*pixbuf_open)
+       else
+               retval->pixbuf = NULL;
+       if (pixbuf_open && *pixbuf_open)
                retval->pixbuf_open = g_object_ref (*pixbuf_open);
-       if (*pixbuf_close)
+       else
+               retval->pixbuf_open = NULL;
+       if (pixbuf_close && *pixbuf_close)
                retval->pixbuf_close = g_object_ref (*pixbuf_close);
+       else
+               retval->pixbuf_close = NULL;
 
        return retval;
 }
 
+static inline ThreePixbufs *
+get_account_protocol_pixbufs (ModestFolderView *folder_view,
+                             ModestProtocolType protocol_type,
+                             GObject *object)
+{
+       ModestProtocol *protocol;
+       const GdkPixbuf *pixbuf = NULL;
+       ModestFolderViewPrivate *priv;
+
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (folder_view);
+
+       protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
+                                                                 protocol_type);
+
+       if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
+               pixbuf = modest_account_protocol_get_icon (MODEST_ACCOUNT_PROTOCOL (protocol), 
+                                                          priv->filter & MODEST_FOLDER_VIEW_FILTER_SHOW_ONLY_MAILBOXES?
+                                                          MODEST_ACCOUNT_PROTOCOL_ICON_MAILBOX:
+                                                          MODEST_ACCOUNT_PROTOCOL_ICON_FOLDER,
+                                                          object, FOLDER_ICON_SIZE);
+       }
+
+       if (pixbuf) {
+               ThreePixbufs *retval;
+               retval = g_slice_new0 (ThreePixbufs);
+               retval->pixbuf = g_object_ref ((GObject *) pixbuf);
+               retval->pixbuf_open = g_object_ref ((GObject *) pixbuf);
+               retval->pixbuf_close = g_object_ref ((GObject *) pixbuf);
+               return retval;
+       } else {
+               return NULL;
+       }
+}
+
 static inline ThreePixbufs*
-get_folder_icons (TnyFolderType type, GObject *instance)
+get_folder_icons (ModestFolderView *folder_view, TnyFolderType type, GObject *instance)
 {
+       TnyAccount *account = NULL;
        static GdkPixbuf *inbox_pixbuf = NULL, *outbox_pixbuf = NULL,
                *junk_pixbuf = NULL, *sent_pixbuf = NULL,
                *trash_pixbuf = NULL, *draft_pixbuf = NULL,
-               *normal_pixbuf = NULL, *anorm_pixbuf = NULL,
+               *normal_pixbuf = NULL, *anorm_pixbuf = NULL, *mmc_pixbuf = NULL,
                *ammc_pixbuf = NULL, *avirt_pixbuf = NULL;
 
        static GdkPixbuf *inbox_pixbuf_open = NULL, *outbox_pixbuf_open = NULL,
                *junk_pixbuf_open = NULL, *sent_pixbuf_open = NULL,
                *trash_pixbuf_open = NULL, *draft_pixbuf_open = NULL,
-               *normal_pixbuf_open = NULL, *anorm_pixbuf_open = NULL,
+               *normal_pixbuf_open = NULL, *anorm_pixbuf_open = NULL, *mmc_pixbuf_open = NULL,
                *ammc_pixbuf_open = NULL, *avirt_pixbuf_open = NULL;
 
        static GdkPixbuf *inbox_pixbuf_close = NULL, *outbox_pixbuf_close = NULL,
                *junk_pixbuf_close = NULL, *sent_pixbuf_close = NULL,
                *trash_pixbuf_close = NULL, *draft_pixbuf_close = NULL,
-               *normal_pixbuf_close = NULL, *anorm_pixbuf_close = NULL,
+               *normal_pixbuf_close = NULL, *anorm_pixbuf_close = NULL, *mmc_pixbuf_close = NULL,
                *ammc_pixbuf_close = NULL, *avirt_pixbuf_close = NULL;
 
        ThreePixbufs *retval = NULL;
 
+       if (TNY_IS_ACCOUNT (instance)) {
+               account = g_object_ref (instance);
+       } else if (TNY_IS_FOLDER (instance) && !TNY_IS_MERGE_FOLDER (instance)) {
+               account = tny_folder_get_account (TNY_FOLDER (instance));
+       }
+
+       if (account) {
+               ModestProtocolType account_store_protocol;
+
+               account_store_protocol = modest_tny_account_get_protocol_type (account);
+               retval = get_account_protocol_pixbufs (folder_view, account_store_protocol, instance);
+               g_object_unref (account);
+       }
+
+       if (retval)
+               return retval;
+
        /* Sometimes an special folder is reported by the server as
           NORMAL, like some versions of Dovecot */
        if (type == TNY_FOLDER_TYPE_NORMAL ||
@@ -845,19 +998,25 @@ get_folder_icons (TnyFolderType type, GObject *instance)
                type = modest_tny_folder_guess_folder_type (TNY_FOLDER (instance));
        }
 
+       /* It's not enough with check the folder type. We need to
+          ensure that we're not giving a special folder icon to a
+          normal folder with the same name than a special folder */
+       if (TNY_IS_FOLDER (instance) &&
+           get_cmp_pos (type, TNY_FOLDER (instance)) ==  4)
+               type = TNY_FOLDER_TYPE_NORMAL;
+
        /* Remote folders should not be treated as special folders */
        if (TNY_IS_FOLDER_STORE (instance) &&
            !TNY_IS_ACCOUNT (instance) &&
            type != TNY_FOLDER_TYPE_INBOX &&
            modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (instance))) {
-               return get_composite_icons (MODEST_FOLDER_ICON_NORMAL,
-                                           &normal_pixbuf,
-                                           &normal_pixbuf_open,
-                                           &normal_pixbuf_close);
+               return get_composite_icons (MODEST_FOLDER_ICON_REMOTE_FOLDER,
+                                           &anorm_pixbuf,
+                                           &anorm_pixbuf_open,
+                                           &anorm_pixbuf_close);
        }
 
        switch (type) {
-               const gchar *icon_code;
 
        case TNY_FOLDER_TYPE_INVALID:
                g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
@@ -924,18 +1083,26 @@ get_folder_icons (TnyFolderType type, GObject *instance)
                                              &draft_pixbuf_open,
                                              &draft_pixbuf_close);
                break;
+       case TNY_FOLDER_TYPE_ARCHIVE:
+               retval = get_composite_icons (MODEST_FOLDER_ICON_MMC_FOLDER,
+                                             &mmc_pixbuf,
+                                             &mmc_pixbuf_open,
+                                             &mmc_pixbuf_close);
+               break;
        case TNY_FOLDER_TYPE_NORMAL:
        default:
                /* Memory card folders could have an special icon */
-               if (modest_tny_folder_is_memory_card_folder (TNY_FOLDER (instance)))
-                       icon_code = MODEST_FOLDER_ICON_MMC_FOLDER;
-               else
-                       icon_code = MODEST_FOLDER_ICON_NORMAL;
-
-               retval = get_composite_icons (icon_code,
-                                             &normal_pixbuf,
-                                             &normal_pixbuf_open,
-                                             &normal_pixbuf_close);
+               if (modest_tny_folder_is_memory_card_folder (TNY_FOLDER (instance))) {
+                       retval = get_composite_icons (MODEST_FOLDER_ICON_MMC_FOLDER,
+                                                     &mmc_pixbuf,
+                                                     &mmc_pixbuf_open,
+                                                     &mmc_pixbuf_close);
+               } else {
+                       retval = get_composite_icons (MODEST_FOLDER_ICON_NORMAL,
+                                                     &normal_pixbuf,
+                                                     &normal_pixbuf_open,
+                                                     &normal_pixbuf_close);
+               }
                break;
        }
 
@@ -965,6 +1132,7 @@ icon_cell_data  (GtkTreeViewColumn *column,
        TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
        gboolean has_children;
        ThreePixbufs *pixbufs;
+       ModestFolderView *folder_view = (ModestFolderView *) data;
 
        rendobj = (GObject *) renderer;
 
@@ -977,7 +1145,7 @@ icon_cell_data  (GtkTreeViewColumn *column,
                return;
 
        has_children = gtk_tree_model_iter_has_child (tree_model, iter);
-       pixbufs = get_folder_icons (type, instance);
+       pixbufs = get_folder_icons (folder_view, type, instance);
        g_object_unref (instance);
 
        /* Set pixbuf */
@@ -1006,17 +1174,19 @@ add_columns (GtkWidget *treeview)
 
        /* Set icon and text render function */
        renderer = gtk_cell_renderer_pixbuf_new();
+       g_object_set (renderer,
+                     "xpad", MODEST_MARGIN_DEFAULT,
+                     "ypad", MODEST_MARGIN_DEFAULT,
+                     NULL);
        gtk_tree_view_column_pack_start (column, renderer, FALSE);
        gtk_tree_view_column_set_cell_data_func(column, renderer,
                                                icon_cell_data, treeview, NULL);
 
        renderer = gtk_cell_renderer_text_new();
        g_object_set (renderer, 
-#ifdef MODEST_TOOLKIT_HILDON2
                      "ellipsize", PANGO_ELLIPSIZE_MIDDLE,
-#else
-                     "ellipsize", PANGO_ELLIPSIZE_END,
-#endif
+                     "ypad", MODEST_MARGIN_DEFAULT,
+                     "xpad", MODEST_MARGIN_DEFAULT,
                      "ellipsize-set", TRUE, NULL);
        gtk_tree_view_column_pack_start (column, renderer, TRUE);
        gtk_tree_view_column_set_cell_data_func(column, renderer,
@@ -1024,8 +1194,9 @@ add_columns (GtkWidget *treeview)
 
        priv->messages_renderer = gtk_cell_renderer_text_new ();
        g_object_set (priv->messages_renderer, 
-                     "scale", PANGO_SCALE_X_SMALL,
-                     "scale-set", TRUE,
+                     "yalign", 0.5,
+                     "ypad", MODEST_MARGIN_DEFAULT,
+                     "xpad", MODEST_MARGIN_DOUBLE,
                      "alignment", PANGO_ALIGN_RIGHT,
                      "align-set", TRUE,
                      "xalign", 1.0,
@@ -1060,12 +1231,15 @@ modest_folder_view_init (ModestFolderView *obj)
        priv->timer_expander = 0;
        priv->account_store  = NULL;
        priv->query          = NULL;
+       priv->do_refresh     = TRUE;
        priv->style          = MODEST_FOLDER_VIEW_STYLE_SHOW_ALL;
        priv->cur_folder_store   = NULL;
        priv->visible_account_id = NULL;
+       priv->mailbox = NULL;
        priv->folder_to_select = NULL;
-
+       priv->outbox_deleted_handler = 0;
        priv->reexpand = TRUE;
+       priv->signal_handlers = 0;
 
        /* Initialize the local account name */
        conf = modest_runtime_get_conf();
@@ -1078,37 +1252,37 @@ modest_folder_view_init (ModestFolderView *obj)
        priv->filter = MODEST_FOLDER_VIEW_FILTER_NONE;
        priv->reselect = FALSE;
        priv->show_non_move = TRUE;
+       priv->list_to_move = NULL;
+       priv->show_message_count = TRUE;
 
        /* Build treeview */
        add_columns (GTK_WIDGET (obj));
 
-       /* Setup drag and drop */
-       setup_drag_and_drop (GTK_TREE_VIEW(obj));
-
        /* Connect signals */
-       g_signal_connect (G_OBJECT (obj),
-                         "key-press-event",
-                         G_CALLBACK (on_key_pressed), NULL);
+       g_signal_connect (G_OBJECT (obj),
+                         "key-press-event",
+                         G_CALLBACK (on_key_pressed), NULL);
 
-       priv->display_name_changed_signal =
-               g_signal_connect (modest_runtime_get_account_mgr (),
-                                 "display_name_changed",
-                                 G_CALLBACK (on_display_name_changed),
-                                 obj);
+       priv->display_name_changed_signal =
+               g_signal_connect (modest_runtime_get_account_mgr (),
+                                 "display_name_changed",
+                                 G_CALLBACK (on_display_name_changed),
+                                 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);
-
-       update_style (obj);
-       g_signal_connect (G_OBJECT (obj), "notify::style", G_CALLBACK (on_notify_style), (gpointer) obj);
+       priv->conf_key_signal = g_signal_connect (G_OBJECT(conf),
+                                                 "key_changed",
+                                                 G_CALLBACK(on_configuration_key_changed),
+                                                 obj);
 
+       gdk_color_parse ("000", &priv->active_color);
 
+       update_style (obj);
+       g_signal_connect (G_OBJECT (obj), "notify::style", 
+                         G_CALLBACK (on_notify_style), (gpointer) obj);
 }
 
 static void
@@ -1120,20 +1294,18 @@ tny_account_store_view_init (gpointer g, gpointer iface_data)
 }
 
 static void
-modest_folder_view_finalize (GObject *obj)
+modest_folder_view_dispose (GObject *obj)
 {
        ModestFolderViewPrivate *priv;
-       GtkTreeSelection    *sel;
-
-       g_return_if_fail (obj);
 
-       priv =  MODEST_FOLDER_VIEW_GET_PRIVATE(obj);
+       priv =  MODEST_FOLDER_VIEW_GET_PRIVATE (obj);
 
-       if (priv->timer_expander != 0) {
-               g_source_remove (priv->timer_expander);
-               priv->timer_expander = 0;
+       if (priv->signal_handlers) {
+               modest_signal_mgr_disconnect_all_and_destroy (priv->signal_handlers);
+               priv->signal_handlers = NULL;
        }
 
+       /* Free external references */
        if (priv->account_store) {
                g_signal_handler_disconnect (G_OBJECT(priv->account_store),
                                             priv->account_inserted_signal);
@@ -1145,13 +1317,6 @@ modest_folder_view_finalize (GObject *obj)
                priv->account_store = NULL;
        }
 
-       if (g_signal_handler_is_connected (modest_runtime_get_account_mgr (), 
-                                          priv->display_name_changed_signal)) {
-               g_signal_handler_disconnect (modest_runtime_get_account_mgr (),
-                                            priv->display_name_changed_signal);
-               priv->display_name_changed_signal = 0;
-       }
-
        if (priv->query) {
                g_object_unref (G_OBJECT (priv->query));
                priv->query = NULL;
@@ -1162,12 +1327,59 @@ modest_folder_view_finalize (GObject *obj)
                priv->folder_to_select = NULL;
        }
 
+       if (priv->cur_folder_store) {
+               g_object_unref (priv->cur_folder_store);
+               priv->cur_folder_store = NULL;
+       }
+
+       if (priv->list_to_move) {
+               g_object_unref (priv->list_to_move);
+               priv->list_to_move = NULL;
+       }
+
+       G_OBJECT_CLASS(parent_class)->dispose (obj);
+}
+
+static void
+modest_folder_view_finalize (GObject *obj)
+{
+       ModestFolderViewPrivate *priv;
+       GtkTreeSelection    *sel;
+       TnyAccount *local_account;
+
+       g_return_if_fail (obj);
+
+       priv =  MODEST_FOLDER_VIEW_GET_PRIVATE(obj);
+
+       if (priv->timer_expander != 0) {
+               g_source_remove (priv->timer_expander);
+               priv->timer_expander = 0;
+       }
+
+       local_account = (TnyAccount *)
+               modest_tny_account_store_get_local_folders_account (modest_runtime_get_account_store ());
+       if (local_account) {
+               if (g_signal_handler_is_connected (local_account,
+                                                  priv->outbox_deleted_handler))
+                       g_signal_handler_disconnect (local_account,
+                                                    priv->outbox_deleted_handler);
+               g_object_unref (local_account);
+       }
+
+       if (g_signal_handler_is_connected (modest_runtime_get_account_mgr (), 
+                                          priv->display_name_changed_signal)) {
+               g_signal_handler_disconnect (modest_runtime_get_account_mgr (),
+                                            priv->display_name_changed_signal);
+               priv->display_name_changed_signal = 0;
+       }
+
        sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(obj));
        if (sel)
                g_signal_handler_disconnect (G_OBJECT(sel), priv->changed_signal);
 
        g_free (priv->local_account_name);
        g_free (priv->visible_account_id);
+       g_free (priv->mailbox);
 
        if (priv->conf_key_signal) {
                g_signal_handler_disconnect (modest_runtime_get_conf (),
@@ -1175,14 +1387,11 @@ modest_folder_view_finalize (GObject *obj)
                priv->conf_key_signal = 0;
        }
 
-       if (priv->cur_folder_store) {
-               g_object_unref (priv->cur_folder_store);
-               priv->cur_folder_store = NULL;
-       }
-
        /* Clear hidding array created by cut operation */
        _clear_hidding_filter (MODEST_FOLDER_VIEW (obj));
 
+       gdk_color_parse ("000", &priv->active_color);
+
        G_OBJECT_CLASS(parent_class)->finalize (obj);
 }
 
@@ -1232,18 +1441,39 @@ modest_folder_view_set_account_store (TnyAccountStoreView *self, TnyAccountStore
 
        modest_folder_view_update_model (MODEST_FOLDER_VIEW (self), account_store);
        priv->reselect = FALSE;
-       modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (self));
 
        g_object_unref (G_OBJECT (device));
 }
 
 static void
+on_outbox_deleted_cb (ModestTnyLocalFoldersAccount *local_account,
+                     gpointer user_data)
+{
+       ModestFolderView *self;
+       GtkTreeModel *model, *filter_model;
+       TnyFolder *outbox;
+
+       self = MODEST_FOLDER_VIEW (user_data);
+
+       if (!get_inner_models (self, &filter_model, NULL, &model))
+               return;
+
+       /* Remove outbox from model */
+       outbox = modest_tny_local_folders_account_get_merged_outbox (local_account);
+       tny_list_remove (TNY_LIST (model), G_OBJECT (outbox));
+       g_object_unref (outbox);
+
+       /* Refilter view */
+       gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
+}
+
+static void
 on_account_inserted (TnyAccountStore *account_store,
                     TnyAccount *account,
                     gpointer user_data)
 {
        ModestFolderViewPrivate *priv;
-       GtkTreeModel *sort_model, *filter_model;
+       GtkTreeModel *model, *filter_model;
 
        /* Ignore transport account insertions, we're not showing them
           in the folder view */
@@ -1261,31 +1491,29 @@ on_account_inserted (TnyAccountStore *account_store,
                                              G_OBJECT (user_data),
                                              MODEST_CONF_FOLDER_VIEW_KEY);
 
-       if (!GTK_IS_TREE_VIEW(user_data)) {
-               g_warning ("BUG: %s: not a valid tree view", __FUNCTION__);
-               return;
-       }
-
-       /* Get the inner model */
-       /* check, is some rare cases, we did not get the right thing here,
-        * NB#84097 */
-       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
-       if (!GTK_IS_TREE_MODEL_FILTER(filter_model)) {
-               g_warning ("BUG: %s: not a valid filter model", __FUNCTION__);
-               return;
-       }
 
-       /* check, is some rare cases, we did not get the right thing here,
-        * NB#84097 */
-       sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
-       if (!GTK_IS_TREE_MODEL_SORT(sort_model)) {
-               g_warning ("BUG: %s: not a valid sort model", __FUNCTION__);
+       /* Get models */
+       if (!get_inner_models (MODEST_FOLDER_VIEW (user_data),
+                              &filter_model, NULL, &model))
                return;
-       }
 
        /* 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));
+       tny_list_append (TNY_LIST (model), G_OBJECT (account));
+
+       /* When the model is a list store (plain representation) the
+          outbox is not a child of any account so we have to manually
+          delete it because removing the local folders account won't
+          delete it (because tny_folder_get_account() is not defined
+          for a merge folder */
+       if (TNY_IS_GTK_FOLDER_LIST_STORE (model) &&
+           MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (account)) {
+
+               priv->outbox_deleted_handler =
+                       g_signal_connect (account,
+                                         "outbox-deleted",
+                                         G_CALLBACK (on_outbox_deleted_cb),
+                                         user_data);
+       }
 
        /* Refilter the model */
        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
@@ -1320,22 +1548,6 @@ same_account_selected (ModestFolderView *self,
        return same_account;
 }
 
-/**
- *
- * Selects the first inbox or the local account in an idle
- */
-static gboolean
-on_idle_select_first_inbox_or_local (gpointer user_data)
-{
-       ModestFolderView *self = MODEST_FOLDER_VIEW (user_data);
-
-       gdk_threads_enter ();
-       modest_folder_view_select_first_inbox_or_local (self);
-       gdk_threads_leave ();
-
-       return FALSE;
-}
-
 static void
 on_account_changed (TnyAccountStore *account_store,
                    TnyAccount *tny_account,
@@ -1343,7 +1555,7 @@ on_account_changed (TnyAccountStore *account_store,
 {
        ModestFolderView *self;
        ModestFolderViewPrivate *priv;
-       GtkTreeModel *sort_model, *filter_model;
+       GtkTreeModel *model, *filter_model;
        GtkTreeSelection *sel;
        gboolean same_account;
 
@@ -1352,26 +1564,15 @@ on_account_changed (TnyAccountStore *account_store,
        if (TNY_IS_TRANSPORT_ACCOUNT (tny_account))
                return;
 
-       if (!MODEST_IS_FOLDER_VIEW(user_data)) {
-               g_warning ("BUG: %s: not a valid folder view", __FUNCTION__);
-               return;
-       }
-
        self = MODEST_FOLDER_VIEW (user_data);
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (user_data);
 
        /* Get the inner model */
-       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
-       if (!GTK_IS_TREE_MODEL_FILTER(filter_model)) {
-               g_warning ("BUG: %s: not a valid filter model", __FUNCTION__);
+       if (!get_inner_models (MODEST_FOLDER_VIEW (user_data),
+                              &filter_model, NULL, &model))
                return;
-       }
 
-       sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
-       if (!GTK_IS_TREE_MODEL_SORT(sort_model)) {
-               g_warning ("BUG: %s: not a valid sort model", __FUNCTION__);
-               return;
-       }
+       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
 
        /* Invalidate the cur_folder_store only if the selected folder
           belongs to the account that is being removed */
@@ -1382,20 +1583,14 @@ on_account_changed (TnyAccountStore *account_store,
        }
 
        /* 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));
+       tny_list_remove (TNY_LIST (model), G_OBJECT (tny_account));
 
        /* 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));
+       tny_list_append (TNY_LIST (model), G_OBJECT (tny_account));
 
        /* Refilter the model */
        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
 
-       /* Select the first INBOX if the currently selected folder
-          belongs to the account that is being deleted */
-       if (same_account && !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (tny_account))
-               g_idle_add (on_idle_select_first_inbox_or_local, self);
 }
 
 static void
@@ -1405,7 +1600,7 @@ on_account_removed (TnyAccountStore *account_store,
 {
        ModestFolderView *self = NULL;
        ModestFolderViewPrivate *priv;
-       GtkTreeModel *sort_model, *filter_model;
+       GtkTreeModel *model, *filter_model;
        GtkTreeSelection *sel = NULL;
        gboolean same_account = FALSE;
 
@@ -1444,21 +1639,21 @@ on_account_removed (TnyAccountStore *account_store,
                g_object_unref (folder_to_select_account);
        }
 
-       /* Remove the account from the model */
-       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
-       if (!GTK_IS_TREE_MODEL_FILTER(filter_model)) {
-               g_warning ("BUG: %s: not a valid filter model", __FUNCTION__);
+       if (!get_inner_models (MODEST_FOLDER_VIEW (user_data),
+                              &filter_model, NULL, &model))
                return;
-       }
 
-       sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
-       if (!GTK_IS_TREE_MODEL_SORT(sort_model)) {
-               g_warning ("BUG: %s: not a valid sort model", __FUNCTION__);
-               return;
+       /* Disconnect the signal handler */
+       if (TNY_IS_GTK_FOLDER_LIST_STORE (model) &&
+           MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (account)) {
+               if (g_signal_handler_is_connected (account,
+                                                  priv->outbox_deleted_handler))
+                       g_signal_handler_disconnect (account,
+                                                    priv->outbox_deleted_handler);
        }
 
-       tny_list_remove (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
-                        G_OBJECT (account));
+       /* Remove the account from the model */
+       tny_list_remove (TNY_LIST (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 */
@@ -1467,6 +1662,7 @@ on_account_removed (TnyAccountStore *account_store,
 
                /* Clear the current visible account_id */
                modest_folder_view_set_account_id_of_visible_server_account (self, NULL);
+               modest_folder_view_set_mailbox (self, NULL);
 
                /* Call the restore method, this will set the new visible account */
                modest_widget_memory_restore (modest_runtime_get_conf(), G_OBJECT(self),
@@ -1476,10 +1672,6 @@ on_account_removed (TnyAccountStore *account_store,
        /* Refilter the model */
        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
 
-       /* Select the first INBOX if the currently selected folder
-          belongs to the account that is being deleted */
-       if (same_account)
-               g_idle_add (on_idle_select_first_inbox_or_local, self);
 }
 
 void
@@ -1520,7 +1712,6 @@ modest_folder_view_on_map (ModestFolderView *self,
                   deathlock situation */
                /* TODO: check if this is still the case */
                priv->reselect = FALSE;
-               modest_folder_view_select_first_inbox_or_local (self);
                /* Notify the display name observers */
                g_signal_emit (G_OBJECT(self),
                               signals[FOLDER_DISPLAY_NAME_CHANGED_SIGNAL], 0,
@@ -1538,6 +1729,12 @@ modest_folder_view_on_map (ModestFolderView *self,
 GtkWidget*
 modest_folder_view_new (TnyFolderStoreQuery *query)
 {
+       return modest_folder_view_new_full (query, TRUE);
+}
+
+GtkWidget*
+modest_folder_view_new_full (TnyFolderStoreQuery *query, gboolean do_refresh)
+{
        GObject *self;
        ModestFolderViewPrivate *priv;
        GtkTreeSelection *sel;
@@ -1552,6 +1749,8 @@ modest_folder_view_new (TnyFolderStoreQuery *query)
        if (query)
                priv->query = g_object_ref (query);
 
+       priv->do_refresh = do_refresh;
+
        sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
        priv->changed_signal = g_signal_connect (sel, "changed",
                                                 G_CALLBACK (on_selection_changed), self);
@@ -1583,44 +1782,176 @@ expand_root_items (ModestFolderView *self)
        gtk_tree_path_free (path);
 }
 
-/*
- * We use this function to implement the
- * MODEST_FOLDER_VIEW_STYLE_SHOW_ONE style. We only show the default
- * account in this case, and the local folders.
- */
 static gboolean
-filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+is_parent_of (TnyFolder *a, TnyFolder *b)
 {
-       ModestFolderViewPrivate *priv;
-       gboolean retval = TRUE;
-       TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
-       GObject *instance = NULL;
-       const gchar *id = NULL;
-       guint i;
-       gboolean found = FALSE;
-       gboolean cleared = FALSE;
-       ModestTnyFolderRules rules = 0;
-
-       g_return_val_if_fail (MODEST_IS_FOLDER_VIEW (data), FALSE);
-       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (data);
+       const gchar *a_id;
+       gboolean retval = FALSE;
 
-       gtk_tree_model_get (model, iter,
-                           TYPE_COLUMN, &type,
-                           INSTANCE_COLUMN, &instance,
-                           -1);
+       a_id = tny_folder_get_id (a);
+       if (a_id) {
+               gchar *string_to_match;
+               const gchar *b_id;
+
+               string_to_match = g_strconcat (a_id, "/", NULL);
+               b_id = tny_folder_get_id (b);
+               retval = g_str_has_prefix (b_id, string_to_match);
+               g_free (string_to_match);
+       }
+       
+       return retval;
+}
+
+typedef struct _ForeachFolderInfo {
+       gchar *needle;
+       gboolean found;
+} ForeachFolderInfo;
+
+static gboolean 
+foreach_folder_with_id (GtkTreeModel *model,
+                       GtkTreePath *path,
+                       GtkTreeIter *iter,
+                       gpointer data)
+{
+       ForeachFolderInfo *info;
+       GObject *instance;
+
+       info = (ForeachFolderInfo *) data;
+       gtk_tree_model_get (model, iter,
+                           INSTANCE_COLUMN, &instance,
+                           -1);
+
+       if (TNY_IS_FOLDER (instance)) {
+               const gchar *id;
+               gchar *collate;
+               id = tny_folder_get_id (TNY_FOLDER (instance));
+               if (id) {
+                       collate = g_utf8_collate_key (id, -1);
+                       info->found = !strcmp (info->needle, collate);
+                       g_free (collate);
+               }
+       }
+
+       if (instance)
+               g_object_unref (instance);
+
+       return info->found;
+       
+}
+
+
+static gboolean
+has_folder_with_id (ModestFolderView *self, const gchar *id)
+{
+       GtkTreeModel *model;
+       ForeachFolderInfo info = {NULL, FALSE};
+
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+       info.needle = g_utf8_collate_key (id, -1);
+       
+       gtk_tree_model_foreach (model, foreach_folder_with_id, &info);
+       g_free (info.needle);
+
+       return info.found;
+}
+
+static gboolean
+has_child_with_name_of (ModestFolderView *self, TnyFolder *a, TnyFolder *b)
+{
+       const gchar *a_id;
+       gboolean retval = FALSE;
+
+       a_id = tny_folder_get_id (a);
+       if (a_id) {
+               const gchar *b_id;
+               b_id = tny_folder_get_id (b);
+               
+               if (b_id) {
+                       const gchar *last_bar;
+                       gchar *string_to_match;
+                       last_bar = g_strrstr (b_id, "/");
+                       if (last_bar)
+                               last_bar++;
+                       else
+                               last_bar = b_id;
+                       string_to_match = g_strconcat (a_id, "/", last_bar, NULL);
+                       retval = has_folder_with_id (self, string_to_match);
+                       g_free (string_to_match);
+               }
+       }
+
+       return retval;
+}
+
+static gboolean
+check_move_to_this_folder_valid (ModestFolderView *self, TnyFolder *folder)
+{
+       ModestFolderViewPrivate *priv;
+       TnyIterator *iterator;
+       gboolean retval = TRUE;
+
+       g_return_val_if_fail (MODEST_IS_FOLDER_VIEW (self), FALSE);
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       for (iterator = tny_list_create_iterator (priv->list_to_move);
+            retval && !tny_iterator_is_done (iterator);
+            tny_iterator_next (iterator)) {
+               GObject *instance;
+               instance = tny_iterator_get_current (iterator);
+               if (instance == (GObject *) folder) {
+                       retval = FALSE;
+               } else if (TNY_IS_FOLDER (instance)) {
+                       retval = !is_parent_of (TNY_FOLDER (instance), folder);
+                       if (retval) {
+                               retval = !has_child_with_name_of (self, folder, TNY_FOLDER (instance));
+                       }
+               }
+               g_object_unref (instance);
+       }
+       g_object_unref (iterator);
+
+       return retval;
+}
+
+
+/*
+ * We use this function to implement the
+ * MODEST_FOLDER_VIEW_STYLE_SHOW_ONE style. We only show the default
+ * account in this case, and the local folders.
+ */
+static gboolean
+filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
+{
+       ModestFolderViewPrivate *priv;
+       gboolean retval = TRUE;
+       TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
+       GObject *instance = NULL;
+       const gchar *id = NULL;
+       guint i;
+       gboolean found = FALSE;
+       gboolean cleared = FALSE;
+       ModestTnyFolderRules rules = 0;
+       gchar *fname;
+
+       g_return_val_if_fail (MODEST_IS_FOLDER_VIEW (data), FALSE);
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (data);
+
+       gtk_tree_model_get (model, iter,
+                           NAME_COLUMN, &fname,
+                           TYPE_COLUMN, &type,
+                           INSTANCE_COLUMN, &instance,
+                           -1);
 
        /* Do not show if there is no instance, this could indeed
           happen when the model is being modified while it's being
           drawn. This could occur for example when moving folders
           using drag&drop */
-       if (!instance)
+       if (!instance) {
+               g_free (fname);
                return FALSE;
+       }
 
        if (TNY_IS_ACCOUNT (instance)) {
-#ifdef MODEST_TOOLKIT_HILDON2
-               /* In hildon 2.2 we don't show the account rows */
-               return FALSE;
-#else
                TnyAccount *acc = TNY_ACCOUNT (instance);
                const gchar *account_id = tny_account_get_id (acc);
 
@@ -1643,7 +1974,6 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
                 * in the local-folders account instead: */
                if (retval && MODEST_IS_TNY_OUTBOX_ACCOUNT (acc))
                        retval = FALSE;
-#endif
        } else {
                if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ONE) {
                        /* Only show special folders for current account if needed */
@@ -1659,8 +1989,17 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
                                            strcmp (account_id, MODEST_MMC_ACCOUNT_ID)) {
                                                /* Show only the visible account id */
                                                if (priv->visible_account_id) {
-                                                       if (strcmp (account_id, priv->visible_account_id))
-                                                               retval = FALSE;
+                                                 if (strcmp (account_id, priv->visible_account_id)) {
+                                                         retval = FALSE;
+                                                 } else if (priv->mailbox) {
+                                                         /* Filter mailboxes */
+                                                         if (!g_str_has_prefix (fname, priv->mailbox)) {
+                                                                 retval = FALSE;
+                                                         } else if (!strcmp (fname, priv->mailbox)) {
+                                                                 /* Hide mailbox parent */
+                                                                 retval = FALSE;
+                                                         }
+                                                 }
                                                }
                                        }
                                                g_object_unref (account);
@@ -1684,8 +2023,15 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
 
        /* 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) {
+       if (retval && !priv->show_non_move) {
+               if (priv->list_to_move && 
+                   tny_list_get_length (priv->list_to_move) > 0 &&
+                   TNY_IS_FOLDER (instance)) {
+                       retval = check_move_to_this_folder_valid (MODEST_FOLDER_VIEW (data), TNY_FOLDER (instance));
+               }
+               if (retval && TNY_IS_FOLDER (instance) && 
+                   modest_tny_folder_is_local_folder (TNY_FOLDER (instance))) {
+                       switch (type) {
                        case TNY_FOLDER_TYPE_OUTBOX:
                        case TNY_FOLDER_TYPE_SENT:
                        case TNY_FOLDER_TYPE_DRAFTS:
@@ -1696,7 +2042,7 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
                                type = modest_tny_folder_guess_folder_type(TNY_FOLDER(instance));
                                if (type == TNY_FOLDER_TYPE_INVALID)
                                        g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
-
+                               
                                if (type == TNY_FOLDER_TYPE_OUTBOX ||
                                    type == TNY_FOLDER_TYPE_SENT
                                    || type == TNY_FOLDER_TYPE_DRAFTS)
@@ -1704,31 +2050,85 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
                                break;
                        default:
                                break;
+                       }
+               }
+               if (retval && TNY_IS_ACCOUNT (instance) &&
+                   modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (instance))) {
+                       ModestProtocolType protocol_type;
+
+                       protocol_type = modest_tny_account_get_protocol_type (TNY_ACCOUNT (instance));
+                       retval  = !modest_protocol_registry_protocol_type_has_tag
+                               (modest_runtime_get_protocol_registry (),
+                                protocol_type,
+                                MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
                }
        }
 
        /* apply special filters */
+       if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_HIDE_ACCOUNTS)) {
+               if (TNY_IS_ACCOUNT (instance))
+                       return FALSE;
+       }
+
+       if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_HIDE_FOLDERS)) {
+               if (TNY_IS_FOLDER (instance))
+                       return FALSE;
+       }
+
+       if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_HIDE_LOCAL_FOLDERS)) {
+               if (TNY_IS_ACCOUNT (instance)) {
+                       if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (instance)))
+                               return FALSE;
+               } else if (TNY_IS_FOLDER (instance)) {
+                       if (modest_tny_folder_is_local_folder (TNY_FOLDER (instance)))
+                               return FALSE;
+               }
+       }
+
+       if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_HIDE_MCC_FOLDERS)) {
+               if (TNY_IS_ACCOUNT (instance)) {
+                       if (modest_tny_account_is_memory_card_account (TNY_ACCOUNT (instance)))
+                               return FALSE;
+               } else if (TNY_IS_FOLDER (instance)) {
+                       if (modest_tny_folder_is_memory_card_folder (TNY_FOLDER (instance)))
+                               return FALSE;
+               }
+       }
+
+       if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_SHOW_ONLY_MAILBOXES)) {
+               /* A mailbox is a fake folder with an @ in the middle of the name */
+               if (!TNY_IS_FOLDER (instance) ||
+                   !(tny_folder_get_caps (TNY_FOLDER (instance)) & TNY_FOLDER_CAPS_NOSELECT)) {
+                       return FALSE;
+               } else {
+                       const gchar *folder_name;
+                       folder_name = tny_folder_get_name (TNY_FOLDER (instance));
+                       if (!folder_name || strchr (folder_name, '@') == NULL)
+                               return FALSE;
+               }
+               
+       }
+
        if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_CAN_HAVE_FOLDERS)) {
                if (TNY_IS_FOLDER (instance)) {
-                       TnyFolderCaps capabilities;
-
-                       capabilities = tny_folder_get_caps (TNY_FOLDER (instance));
-                       retval = !(capabilities & TNY_FOLDER_CAPS_NOCHILDREN);
+                       /* Check folder rules */
+                       ModestTnyFolderRules rules;
 
-                       if (retval) {
-                               retval = ((type != TNY_FOLDER_TYPE_DRAFTS) &&
-                                         (type != TNY_FOLDER_TYPE_OUTBOX) &&
-                                         (type != TNY_FOLDER_TYPE_SENT));
-                       }
+                       rules = modest_tny_folder_get_rules (TNY_FOLDER (instance));
+                       retval = !(rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE);
                } else if (TNY_IS_ACCOUNT (instance)) {
-                       retval = FALSE;
+                       if (modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (instance))) {
+                               retval = FALSE;
+                       } else {
+                               retval = TRUE;
+                       }
                }
        }
 
        if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_HIDE_MANDATORY_FOLDERS)) {
                if (TNY_IS_FOLDER (instance)) {
                        TnyFolderType guess_type;
-                       
+
                        if (TNY_FOLDER_TYPE_NORMAL) {
                                guess_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (instance));
                        } else {
@@ -1749,7 +2149,7 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
                        default:
                                break;
                        }
-                       
+
                } else if (TNY_IS_ACCOUNT (instance)) {
                        retval = FALSE;
                }
@@ -1785,6 +2185,7 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
 
        /* Free */
        g_object_unref (instance);
+        g_free (fname);
 
        return retval;
 }
@@ -1795,7 +2196,7 @@ modest_folder_view_update_model (ModestFolderView *self,
                                 TnyAccountStore *account_store)
 {
        ModestFolderViewPrivate *priv;
-       GtkTreeModel *model /* , *old_model */;
+       GtkTreeModel *model;
        GtkTreeModel *filter_model = NULL, *sortable = NULL;
 
        g_return_val_if_fail (self && MODEST_IS_FOLDER_VIEW (self), FALSE);
@@ -1815,19 +2216,84 @@ modest_folder_view_update_model (ModestFolderView *self,
 
        /* FIXME: the local accounts are not shown when the query
           selects only the subscribed folders */
-#ifdef MODEST_TOOLKIT_HILDON2
+       TnyGtkFolderListStoreFlags flags;
+       flags = TNY_GTK_FOLDER_LIST_STORE_FLAG_SHOW_PATH;
+       if (priv->do_refresh)
+               flags |= TNY_GTK_FOLDER_LIST_STORE_FLAG_DELAYED_REFRESH;
+       else
+               flags |= TNY_GTK_FOLDER_LIST_STORE_FLAG_NO_REFRESH;
        model = tny_gtk_folder_list_store_new_with_flags (NULL, 
-                                                         TNY_GTK_FOLDER_LIST_STORE_FLAG_SHOW_PATH);
+                                                         flags);
        tny_gtk_folder_list_store_set_path_separator (TNY_GTK_FOLDER_LIST_STORE (model),
                                                      MODEST_FOLDER_PATH_SEPARATOR);
-#else
-       model = tny_gtk_folder_store_tree_model_new (NULL);
-#endif
 
-       /* Get the accounts: */
-       tny_account_store_get_accounts (TNY_ACCOUNT_STORE(account_store),
-                                       TNY_LIST (model),
-                                       TNY_ACCOUNT_STORE_STORE_ACCOUNTS);
+       /* When the model is a list store (plain representation) the
+          outbox is not a child of any account so we have to manually
+          delete it because removing the local folders account won't
+          delete it (because tny_folder_get_account() is not defined
+          for a merge folder */
+       if (TNY_IS_GTK_FOLDER_LIST_STORE (model)) {
+               TnyAccount *account;
+               ModestTnyAccountStore *acc_store;
+
+               acc_store = modest_runtime_get_account_store ();
+               account = modest_tny_account_store_get_local_folders_account (acc_store);
+
+               if (g_signal_handler_is_connected (account,
+                                                  priv->outbox_deleted_handler))
+                       g_signal_handler_disconnect (account,
+                                                    priv->outbox_deleted_handler);
+
+               priv->outbox_deleted_handler =
+                       g_signal_connect (account,
+                                         "outbox-deleted",
+                                         G_CALLBACK (on_outbox_deleted_cb),
+                                         self);
+               g_object_unref (account);
+       }
+
+       if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ALL) {
+               /* Get the accounts */
+               tny_account_store_get_accounts (TNY_ACCOUNT_STORE(account_store),
+                                               TNY_LIST (model),
+                                               TNY_ACCOUNT_STORE_STORE_ACCOUNTS);
+       } else {
+               if (priv->visible_account_id) {
+                       TnyAccount *account;
+
+                       /* Add local folders account */
+                      account = modest_tny_account_store_get_local_folders_account ((ModestTnyAccountStore *) account_store);
+
+                       if (account) {
+                               tny_list_append (TNY_LIST (model), (GObject *) account);
+                               g_object_unref (account);
+                       }
+
+                      account = modest_tny_account_store_get_mmc_folders_account ((ModestTnyAccountStore *) account_store);
+
+                       if (account) {
+                               tny_list_append (TNY_LIST (model), (GObject *) account);
+                               g_object_unref (account);
+                       }
+
+                       /* Add visible account */
+                      account = modest_tny_account_store_get_tny_account_by ((ModestTnyAccountStore *) account_store,
+                                                                             MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
+                                                                              priv->visible_account_id);
+                       if (account) {
+                               tny_list_append (TNY_LIST (model), (GObject *) account);
+                               g_object_unref (account);
+                       } else {
+                               g_warning ("You need to set an account first");
+                               g_object_unref (model);
+                               return FALSE;
+                       }
+               } else {
+                       g_warning ("You need to set an account first");
+                       g_object_unref (model);
+                       return FALSE;
+               }
+       }
 
        sortable = gtk_tree_model_sort_new_with_model (model);
        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sortable),
@@ -1844,12 +2310,23 @@ modest_folder_view_update_model (ModestFolderView *self,
                                                self,
                                                NULL);
 
+       GtkTreeModel *old_tny_model = NULL;
+       if (get_inner_models (self, NULL, NULL, &old_tny_model)) {
+               if (priv->signal_handlers > 0) {
+                       priv->signal_handlers = modest_signal_mgr_disconnect (priv->signal_handlers,
+                                                                             G_OBJECT (old_tny_model), 
+                                                                             "activity-changed");
+               }
+       }
+
        /* Set new model */
        gtk_tree_view_set_model (GTK_TREE_VIEW(self), filter_model);
-#ifndef MODEST_TOOLKIT_HILDON2
-       g_signal_connect (G_OBJECT(filter_model), "row-inserted",
-                         (GCallback) on_row_inserted_maybe_select_folder, self);
-#endif
+
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT (model),
+                                                          "activity-changed",
+                                                          G_CALLBACK (on_activity_changed),
+                                                          self);
 
        g_object_unref (model);
        g_object_unref (filter_model);
@@ -1901,9 +2378,6 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
                   cause (and it actually does it) a free of the
                   summary of the folder (because the main window will
                   clear the headers view */
-               if (TNY_IS_FOLDER(priv->cur_folder_store))
-                       tny_folder_sync_async (TNY_FOLDER(priv->cur_folder_store),
-                                              FALSE, NULL, NULL, NULL);
 
                g_signal_emit (G_OBJECT(tree_view), signals[FOLDER_SELECTION_CHANGED_SIGNAL], 0,
                       priv->cur_folder_store, FALSE);
@@ -2006,13 +2480,39 @@ get_cmp_rows_type_pos (GObject *folder)
        }
 }
 
+static gboolean
+inbox_is_special (TnyFolderStore *folder_store)
+{
+       gboolean is_special = TRUE;
+
+       if (TNY_IS_FOLDER (folder_store)) {
+               const gchar *id;
+               gchar *downcase;
+               gchar *last_bar;
+               gchar *last_inbox_bar;
+
+               id = tny_folder_get_id (TNY_FOLDER (folder_store));
+               downcase = g_utf8_strdown (id, -1);
+               last_bar = g_strrstr (downcase, "/");
+               if (last_bar) {
+                       last_inbox_bar = g_strrstr  (downcase, "inbox/");
+                       if ((last_inbox_bar == NULL) || (last_inbox_bar + 5 != last_bar))
+                               is_special = FALSE;
+               } else {
+                       is_special = FALSE;
+               }
+               g_free (downcase);
+       }
+       return is_special;
+}
+
 static gint
 get_cmp_pos (TnyFolderType t, TnyFolder *folder_store)
 {
        TnyAccount *account;
        gboolean is_special;
        /* Inbox, Outbox, Drafts, Sent, User */
-       /* 0, 1, 2, 3, 4 */
+       /* 0, 1, 2, 3, 4 */
 
        if (!TNY_IS_FOLDER (folder_store))
                return 4;
@@ -2021,12 +2521,18 @@ get_cmp_pos (TnyFolderType t, TnyFolder *folder_store)
        {
                account = tny_folder_get_account (folder_store);
                is_special = (get_cmp_rows_type_pos (G_OBJECT (account)) == 0);
+
+               /* In inbox case we need to know if the inbox is really the top
+                * inbox of the account, or if it's a submailbox inbox. To do
+                * this we'll apply an heuristic rule: Find last "/" and check
+                * if it's preceeded by another Inbox */
+               is_special = is_special && !inbox_is_special (TNY_FOLDER_STORE (folder_store));
                g_object_unref (account);
                return is_special?0:4;
        }
        break;
        case TNY_FOLDER_TYPE_OUTBOX:
-               return 2;
+               return (TNY_IS_MERGE_FOLDER (folder_store))?2:4;
                break;
        case TNY_FOLDER_TYPE_DRAFTS:
        {
@@ -2063,21 +2569,31 @@ compare_account_names (TnyAccount *a1, TnyAccount *a2)
 static gint
 compare_accounts (TnyFolderStore *s1, TnyFolderStore *s2)
 {
-       TnyAccount *a1, *a2;
+       TnyAccount *a1 = NULL, *a2 = NULL;
        gint cmp;
 
        if (TNY_IS_ACCOUNT (s1)) {
                a1 = TNY_ACCOUNT (g_object_ref (s1));
-       } else {
+       } else if (!TNY_IS_MERGE_FOLDER (s1)) {
                a1 = tny_folder_get_account (TNY_FOLDER (s1));
        }
 
        if (TNY_IS_ACCOUNT (s2)) {
                a2 = TNY_ACCOUNT (g_object_ref (s2));
-       } else {
+       } else  if (!TNY_IS_MERGE_FOLDER (s2)) {
                a2 = tny_folder_get_account (TNY_FOLDER (s2));
        }
 
+       if (!a1 || !a2) {
+               if (!a1 && !a2)
+                       cmp = 0;
+               else if (!a1)
+                       cmp = 1;
+               else
+                       cmp = -1;
+               goto finish;
+       }
+
        if (a1 == a2) {
                cmp = 0;
                goto finish;
@@ -2090,8 +2606,10 @@ compare_accounts (TnyFolderStore *s1, TnyFolderStore *s2)
        cmp = compare_account_names (a1, a2);
 
 finish:
-       g_object_unref (a1);
-       g_object_unref (a2);
+       if (a1)
+               g_object_unref (a1);
+       if (a2)
+               g_object_unref (a2);
 
        return cmp;
 }
@@ -2107,6 +2625,51 @@ compare_accounts_first (TnyFolderStore *s1, TnyFolderStore *s2)
        return is_account2 - is_account1;
 }
 
+static gint
+compare_folders (const gchar *name1, const gchar *name2)
+{
+       const gchar *separator1, *separator2;
+       const gchar *next1, *next2;
+       gchar *top1, *top2;
+       gint cmp;
+
+       if (name1 == NULL || name1[0] == '\0')
+               return -1;
+       if (name2 == NULL || name2[0] == '\0')
+               return 1;
+
+       separator1 = strstr (name1, MODEST_FOLDER_PATH_SEPARATOR);
+       if (separator1) {
+               top1 = g_strndup (name1, separator1 - name1);
+       } else {
+               top1 = g_strdup (name1);
+       }
+
+       separator2 = strstr (name2, MODEST_FOLDER_PATH_SEPARATOR);
+       if (separator2) {
+               top2 = g_strndup (name2, separator2 - name2);
+       } else {
+               top2 = g_strdup (name2);
+       }
+
+
+       cmp = modest_text_utils_utf8_strcmp (top1, top2, TRUE);
+       g_free (top1);
+       g_free (top2);
+
+       if (cmp != 0)
+               return cmp;
+
+       if (separator1 == NULL && separator2 == NULL)
+               return 0;
+
+       next1 = (separator1 != NULL)?separator1 + strlen (MODEST_FOLDER_PATH_SEPARATOR):NULL;
+       next2 = (separator2 != NULL)?separator2 + strlen (MODEST_FOLDER_PATH_SEPARATOR):NULL;
+
+       return compare_folders (next1, next2);
+}
+
+
 /*
  * This function orders the mail accounts according to these rules:
  * 1st - remote accounts
@@ -2149,17 +2712,20 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
                goto finish;
 
        /* Now we sort using the account of each folder */
-       cmp = compare_accounts (TNY_FOLDER_STORE (folder1), TNY_FOLDER_STORE (folder2));
-       if (cmp != 0)
-               goto finish;
+       if (TNY_IS_FOLDER_STORE (folder1) && 
+           TNY_IS_FOLDER_STORE (folder2)) {
+               cmp = compare_accounts (TNY_FOLDER_STORE (folder1), TNY_FOLDER_STORE (folder2));
+               if (cmp != 0)
+                       goto finish;
 
-       /* Each group is preceeded by its account */
-       cmp = compare_accounts_first (TNY_FOLDER_STORE (folder1), TNY_FOLDER_STORE (folder2));
-       if (cmp != 0)
-               goto finish;
+               /* Each group is preceeded by its account */
+               cmp = compare_accounts_first (TNY_FOLDER_STORE (folder1), TNY_FOLDER_STORE (folder2));
+               if (cmp != 0)
+                       goto finish;
+       }
 
        /* Pure sort by name */
-       cmp = modest_text_utils_utf8_strcmp (name1, name2, TRUE);
+       cmp = compare_folders (name1, name2);
  finish:
        if (folder1)
                g_object_unref(G_OBJECT(folder1));
@@ -2172,746 +2738,76 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
        return cmp;
 }
 
-/*****************************************************************************/
-/*                        DRAG and DROP stuff                                */
-/*****************************************************************************/
+
 /*
- * This function fills the #GtkSelectionData with the row and the
- * model that has been dragged. It's called when this widget is a
- * source for dnd after the event drop happened
+ * This function manages the navigation through the folders using the
+ * keyboard or the hardware keys in the device
  */
-static void
-on_drag_data_get (GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,
-                 guint info, guint time, gpointer data)
+static gboolean
+on_key_pressed (GtkWidget *self,
+               GdkEventKey *event,
+               gpointer user_data)
 {
        GtkTreeSelection *selection;
-       GtkTreeModel *model;
        GtkTreeIter iter;
-       GtkTreePath *source_row;
-
-       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
-       if (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);
-
-               gtk_tree_path_free (source_row);
-       }
-}
+       GtkTreeModel *model;
+       gboolean retval = FALSE;
 
-typedef struct _DndHelper {
-       ModestFolderView *folder_view;
-       gboolean delete_source;
-       GtkTreePath *source_row;
-} DndHelper;
+       /* Up and Down are automatically managed by the treeview */
+       if (event->keyval == GDK_Return) {
+               /* Expand/Collapse the selected row */
+               selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+               if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+                       GtkTreePath *path;
 
-static void
-dnd_helper_destroyer (DndHelper *helper)
-{
-       /* Free the helper */
-       gtk_tree_path_free (helper->source_row);
-       g_slice_free (DndHelper, helper);
-}
+                       path = gtk_tree_model_get_path (model, &iter);
 
-static void
-xfer_folder_cb (ModestMailOperation *mail_op,
-               TnyFolder *new_folder,
-               gpointer user_data)
-{
-       if (new_folder) {
-               /* Select the folder */
-               modest_folder_view_select_folder (MODEST_FOLDER_VIEW (user_data),
-                                                 new_folder, FALSE);
+                       if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (self), path))
+                               gtk_tree_view_collapse_row (GTK_TREE_VIEW (self), path);
+                       else
+                               gtk_tree_view_expand_row (GTK_TREE_VIEW (self), path, FALSE);
+                       gtk_tree_path_free (path);
+               }
+               /* No further processing */
+               retval = TRUE;
        }
-}
-
-
-/* get the folder for the row the treepath refers to. */
-/* folder must be unref'd */
-static TnyFolderStore *
-tree_path_to_folder (GtkTreeModel *model, GtkTreePath *path)
-{
-       GtkTreeIter iter;
-       TnyFolderStore *folder = NULL;
 
-       if (gtk_tree_model_get_iter (model,&iter, path))
-               gtk_tree_model_get (model, &iter,
-                                   INSTANCE_COLUMN, &folder,
-                                   -1);
-       return folder;
+       return retval;
 }
 
-
 /*
- * 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
- * view.
+ * We listen to the changes in the local folder account name key,
+ * because we want to show the right name in the view. The local
+ * folder account name corresponds to the device name in the Maemo
+ * version. We do this because we do not want to query gconf on each
+ * tree view refresh. It's better to cache it and change whenever
+ * necessary.
  */
 static void
-drag_and_drop_from_header_view (GtkTreeModel *source_model,
-                               GtkTreeModel *dest_model,
-                               GtkTreePath  *dest_row,
-                               GtkSelectionData *selection_data)
+on_configuration_key_changed (ModestConf* conf,
+                             const gchar *key,
+                             ModestConfEvent event,
+                             ModestConfNotificationId id,
+                             ModestFolderView *self)
 {
-       TnyList *headers = NULL;
-       TnyFolder *folder = NULL, *src_folder = NULL;
-       TnyFolderType folder_type;
-       GtkTreeIter source_iter, dest_iter;
-       ModestWindowMgr *mgr = NULL;
-       ModestWindow *main_win = NULL;
-       gchar **uris, **tmp;
-
-       /* Build the list of headers */
-       mgr = modest_runtime_get_window_mgr ();
-       headers = tny_simple_list_new ();
-       uris = modest_dnd_selection_data_get_paths (selection_data);
-       tmp = uris;
-
-       while (*tmp != NULL) {
-               TnyHeader *header;
-               GtkTreePath *path;
-               gboolean first = TRUE;
-
-               /* Get header */
-               path = gtk_tree_path_new_from_string (*tmp);
-               gtk_tree_model_get_iter (source_model, &source_iter, path);
-               gtk_tree_model_get (source_model, &source_iter,
-                                   TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
-                                   &header, -1);
-
-               /* Do not enable d&d of headers already opened */
-               if (!modest_window_mgr_find_registered_header(mgr, header, NULL))
-                       tny_list_append (headers, G_OBJECT (header));
-
-               if (G_UNLIKELY (first)) {
-                       src_folder = tny_header_get_folder (header);
-                       first = FALSE;
-               }
+       ModestFolderViewPrivate *priv;
 
-               /* Free and go on */
-               gtk_tree_path_free (path);
-               g_object_unref (header);
-               tmp++;
-       }
-       g_strfreev (uris);
 
-       /* This could happen ig we perform a d&d very quickly over the
-          same row that row could dissapear because message is
-          transferred */
-       if (!TNY_IS_FOLDER (src_folder))
-               goto cleanup;
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self);
 
-       /* Get the target folder */
-       gtk_tree_model_get_iter (dest_model, &dest_iter, dest_row);
-       gtk_tree_model_get (dest_model, &dest_iter,
-                           INSTANCE_COLUMN,
-                           &folder, -1);
+       if (!strcmp (key, MODEST_CONF_DEVICE_NAME)) {
+               g_free (priv->local_account_name);
 
-       if (!folder || !TNY_IS_FOLDER(folder)) {
-/*             g_warning ("%s: not a valid target folder (%p)", __FUNCTION__, folder); */
-               goto cleanup;
-       }
+               if (event == MODEST_CONF_EVENT_KEY_UNSET)
+                       priv->local_account_name = g_strdup (MODEST_LOCAL_FOLDERS_DEFAULT_DISPLAY_NAME);
+               else
+                       priv->local_account_name = modest_conf_get_string (modest_runtime_get_conf(),
+                                                                          MODEST_CONF_DEVICE_NAME, NULL);
 
-       folder_type = modest_tny_folder_guess_folder_type (folder);
-       if (folder_type == TNY_FOLDER_TYPE_INVALID) {
-/*             g_warning ("%s: invalid target folder", __FUNCTION__); */
-               goto cleanup;  /* cannot move messages there */
-       }
-
-       if (modest_tny_folder_get_rules((TNY_FOLDER(folder))) & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
-/*             g_warning ("folder not writable"); */
-               goto cleanup; /* verboten! */
-       }
-
-       /* Ask for confirmation to move */
-       main_win = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
-       if (!main_win) {
-               g_warning ("%s: BUG: no main window found", __FUNCTION__);
-               goto cleanup;
-       }
-
-       /* Transfer messages */
-       modest_ui_actions_transfer_messages_helper (GTK_WINDOW (main_win), src_folder,
-                                                   headers, folder);
-
-       /* Frees */
-cleanup:
-       if (G_IS_OBJECT (src_folder))
-               g_object_unref (src_folder);
-       if (G_IS_OBJECT(folder))
-               g_object_unref (G_OBJECT (folder));
-       if (G_IS_OBJECT(headers))
-               g_object_unref (headers);
-}
-
-typedef struct {
-       TnyFolderStore *src_folder;
-       TnyFolderStore *dst_folder;
-       ModestFolderView *folder_view;
-       DndHelper *helper;
-} DndFolderInfo;
-
-static void
-dnd_folder_info_destroyer (DndFolderInfo *info)
-{
-       if (info->src_folder)
-               g_object_unref (info->src_folder);
-       if (info->dst_folder)
-               g_object_unref (info->dst_folder);
-       g_slice_free (DndFolderInfo, info);
-}
-
-static void
-dnd_on_connection_failed_destroyer (DndFolderInfo *info,
-                                   GtkWindow *parent_window,
-                                   TnyAccount *account)
-{
-       /* Show error */
-       modest_ui_actions_on_account_connection_error (parent_window, account);
-
-       /* Free the helper & info */
-       dnd_helper_destroyer (info->helper);
-       dnd_folder_info_destroyer (info);
-}
-
-static void
-drag_and_drop_from_folder_view_src_folder_performer (gboolean canceled,
-                                                    GError *err,
-                                                    GtkWindow *parent_window,
-                                                    TnyAccount *account,
-                                                    gpointer user_data)
-{
-       DndFolderInfo *info = NULL;
-       ModestMailOperation *mail_op;
-
-       info = (DndFolderInfo *) user_data;
-
-       if (err || canceled) {
-               dnd_on_connection_failed_destroyer (info, parent_window, account);
-               return;
-       }
-
-       /* Do the mail operation */
-       mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
-                                                                modest_ui_actions_move_folder_error_handler,
-                                                                info->src_folder, NULL);
-
-       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
-                                        mail_op);
-
-       /* Transfer the folder */
-       modest_mail_operation_xfer_folder (mail_op,
-                                          TNY_FOLDER (info->src_folder),
-                                          info->dst_folder,
-                                          info->helper->delete_source,
-                                          xfer_folder_cb,
-                                          info->helper->folder_view);
-
-       /* Frees */
-       g_object_unref (G_OBJECT (mail_op));
-       dnd_helper_destroyer (info->helper);
-       dnd_folder_info_destroyer (info);
-}
-
-
-static void
-drag_and_drop_from_folder_view_dst_folder_performer (gboolean canceled,
-                                                    GError *err,
-                                                    GtkWindow *parent_window,
-                                                    TnyAccount *account,
-                                                    gpointer user_data)
-{
-       DndFolderInfo *info = NULL;
-
-       info = (DndFolderInfo *) user_data;
-
-       if (err || canceled) {
-               dnd_on_connection_failed_destroyer (info, parent_window, account);
-               return;
-       }
-
-       /* Connect to source folder and perform the copy/move */
-       modest_platform_connect_if_remote_and_perform (NULL, TRUE,
-                                                      info->src_folder,
-                                                      drag_and_drop_from_folder_view_src_folder_performer,
-                                                      info);
-}
-
-/*
- * This function is used by drag_data_received_cb to manage drag and
- * drop of a folder, i.e, and drag from the folder view to the same
- * folder view.
- */
-static void
-drag_and_drop_from_folder_view (GtkTreeModel     *source_model,
-                               GtkTreeModel     *dest_model,
-                               GtkTreePath      *dest_row,
-                               GtkSelectionData *selection_data,
-                               DndHelper        *helper)
-{
-       GtkTreeIter dest_iter, iter;
-       TnyFolderStore *dest_folder = NULL;
-       TnyFolderStore *folder = NULL;
-       gboolean forbidden = FALSE;
-       ModestWindow *win;
-       DndFolderInfo *info = NULL;
-
-       win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE); /* don't create */
-       if (!win) {
-               g_warning ("%s: BUG: no main window", __FUNCTION__);
-               dnd_helper_destroyer (helper);
-               return;
-       }
-
-       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 (TNY_FOLDER (folder));
-                       forbidden = rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE;
-               } else if (TNY_IS_FOLDER_STORE(folder)) {
-                       /* enable local root as destination for folders */
-                       if (!MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder) &&
-                           !modest_tny_account_is_memory_card_account (TNY_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 (TNY_IS_FOLDER(folder)) {
-                       ModestTnyFolderRules rules =
-                               modest_tny_folder_get_rules (TNY_FOLDER (folder));
-                       forbidden = rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE;
-               } else
-                       forbidden = TRUE;
-               g_object_unref (folder);
-       }
-
-
-       /* Check if the drag is possible */
-       if (forbidden || !gtk_tree_path_compare (helper->source_row, dest_row)) {
-               /* Show error */
-               modest_platform_run_information_dialog ((GtkWindow *) win, 
-                                                       _("mail_in_ui_folder_move_target_error"), 
-                                                       FALSE);
-               /* Restore the previous selection */
-               folder = tree_path_to_folder (source_model, helper->source_row);
-               if (folder) {
-                       if (TNY_IS_FOLDER (folder))
-                               modest_folder_view_select_folder (helper->folder_view, 
-                                                                 TNY_FOLDER (folder), FALSE);
-                       g_object_unref (folder);
-               }
-               dnd_helper_destroyer (helper);
-               return;
-       }
-
-       /* Get data */
-       gtk_tree_model_get_iter (dest_model, &dest_iter, dest_row);
-       gtk_tree_model_get (dest_model, &dest_iter,
-                           INSTANCE_COLUMN,
-                           &dest_folder, -1);
-       gtk_tree_model_get_iter (source_model, &iter, helper->source_row);
-       gtk_tree_model_get (source_model, &iter,
-                           INSTANCE_COLUMN,
-                           &folder, -1);
-
-       /* Create the info for the performer */
-       info = g_slice_new0 (DndFolderInfo);
-       info->src_folder = g_object_ref (folder);
-       info->dst_folder = g_object_ref (dest_folder);
-       info->helper = helper;
-
-       /* Connect to the destination folder and perform the copy/move */
-       modest_platform_connect_if_remote_and_perform (GTK_WINDOW (win), TRUE,
-                                                      dest_folder,
-                                                      drag_and_drop_from_folder_view_dst_folder_performer,
-                                                      info);
-
-       /* Frees */
-       g_object_unref (dest_folder);
-       g_object_unref (folder);
-}
-
-/*
- * This function receives the data set by the "drag-data-get" signal
- * handler. This information comes within the #GtkSelectionData. This
- * function will manage both the drags of folders of the treeview and
- * drags of headers of the header view widget.
- */
-static void
-on_drag_data_received (GtkWidget *widget,
-                      GdkDragContext *context,
-                      gint x,
-                      gint y,
-                      GtkSelectionData *selection_data,
-                      guint target_type,
-                      guint time,
-                      gpointer data)
-{
-       GtkWidget *source_widget;
-       GtkTreeModel *dest_model, *source_model;
-       GtkTreePath *source_row, *dest_row;
-       GtkTreeViewDropPosition pos;
-       gboolean delete_source = FALSE;
-       gboolean success = FALSE;
-
-       /* 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 */
-       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 (source_widget == widget) {
-                       GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
-                       gtk_tree_selection_unselect_all (sel);
-               }
-       }
-
-       /* Check if the get_data failed */
-       if (selection_data == NULL || selection_data->length < 0)
-               goto end;
-
-       /* Select the destination model */
-       dest_model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
-
-       /* Get the path to the destination row. Can not call
-          gtk_tree_view_get_drag_dest_row() because the source row
-          is not selected anymore */
-       gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget), x, y,
-                                          &dest_row, &pos);
-
-       /* Only allow drops IN other rows */
-       if (!dest_row ||
-           pos == GTK_TREE_VIEW_DROP_BEFORE ||
-           pos == GTK_TREE_VIEW_DROP_AFTER)
-               goto end;
-
-       success = TRUE;
-       /* Drags from the header view */
-       if (source_widget != widget) {
-               source_model = gtk_tree_view_get_model (GTK_TREE_VIEW (source_widget));
-
-               drag_and_drop_from_header_view (source_model,
-                                               dest_model,
-                                               dest_row,
-                                               selection_data);
-       } else {
-               DndHelper *helper = NULL;
-
-               /* Get the source model and row */
-               gtk_tree_get_row_drag_data (selection_data,
-                                           &source_model,
-                                           &source_row);
-
-               /* Create the helper */
-               helper = g_slice_new0 (DndHelper);
-               helper->delete_source = delete_source;
-               helper->source_row = gtk_tree_path_copy (source_row);
-               helper->folder_view = MODEST_FOLDER_VIEW (widget);
-
-               drag_and_drop_from_folder_view (source_model,
-                                               dest_model,
-                                               dest_row,
-                                               selection_data,
-                                               helper);
-
-               gtk_tree_path_free (source_row);
-       }
-
-       /* Frees */
-       gtk_tree_path_free (dest_row);
-
- end:
-       /* Finish the drag and drop */
-       gtk_drag_finish (context, success, FALSE, time);
-}
-
-/*
- * We define a "drag-drop" signal handler because we do not want to
- * use the default one, because the default one always calls
- * gtk_drag_finish and we prefer to do it in the "drag-data-received"
- * signal handler, because there we have all the information available
- * to know if the dnd was a success or not.
- */
-static gboolean
-drag_drop_cb (GtkWidget      *widget,
-             GdkDragContext *context,
-             gint            x,
-             gint            y,
-             guint           time,
-             gpointer        user_data)
-{
-       gpointer target;
-
-       if (!context->targets)
-               return FALSE;
-
-       /* Check if we're dragging a folder row */
-       target = gtk_drag_dest_find_target (widget, context, NULL);
-
-       /* Request the data from the source. */
-       gtk_drag_get_data(widget, context, target, time);
-
-    return TRUE;
-}
-
-/*
- * This function expands a node of a tree view if it's not expanded
- * yet. Not sure why it needs the threads stuff, but gtk+`example code
- * does that, so that's why they're here.
- */
-static gint
-expand_row_timeout (gpointer data)
-{
-       GtkTreeView *tree_view = data;
-       GtkTreePath *dest_path = NULL;
-       GtkTreeViewDropPosition pos;
-       gboolean result = FALSE;
-
-       gdk_threads_enter ();
-
-       gtk_tree_view_get_drag_dest_row (tree_view,
-                                        &dest_path,
-                                        &pos);
-
-       if (dest_path &&
-           (pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER ||
-            pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE)) {
-               gtk_tree_view_expand_row (tree_view, dest_path, FALSE);
-               gtk_tree_path_free (dest_path);
-       }
-       else {
-               if (dest_path)
-                       gtk_tree_path_free (dest_path);
-
-               result = TRUE;
-       }
-
-       gdk_threads_leave ();
-
-       return result;
-}
-
-/*
- * This function is called whenever the pointer is moved over a widget
- * while dragging some data. It installs a timeout that will expand a
- * node of the treeview if not expanded yet. This function also calls
- * gdk_drag_status in order to set the suggested action that will be
- * used by the "drag-data-received" signal handler to know if we
- * should do a move or just a copy of the data.
- */
-static gboolean
-on_drag_motion (GtkWidget      *widget,
-               GdkDragContext *context,
-               gint            x,
-               gint            y,
-               guint           time,
-               gpointer        user_data)
-{
-       GtkTreeViewDropPosition pos;
-       GtkTreePath *dest_row;
-       GtkTreeModel *dest_model;
-       ModestFolderViewPrivate *priv;
-       GdkDragAction suggested_action;
-       gboolean valid_location = FALSE;
-       TnyFolderStore *folder = NULL;
-
-       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (widget);
-
-       if (priv->timer_expander != 0) {
-               g_source_remove (priv->timer_expander);
-               priv->timer_expander = 0;
-       }
-
-       gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
-                                          x, y,
-                                          &dest_row,
-                                          &pos);
-
-       /* Do not allow drops between folders */
-       if (!dest_row ||
-           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);
-               valid_location = FALSE;
-               goto out;
-       } else {
-               valid_location = TRUE;
-       }
-
-       /* Check that the destination folder is writable */
-       dest_model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
-       folder = tree_path_to_folder (dest_model, dest_row);
-       if (folder && TNY_IS_FOLDER (folder)) {
-               ModestTnyFolderRules rules = modest_tny_folder_get_rules(TNY_FOLDER (folder));
-
-               if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
-                       valid_location = FALSE;
-                       goto out;
-               }
-       }
-
-       /* Expand the selected row after 1/2 second */
-       if (!gtk_tree_view_row_expanded (GTK_TREE_VIEW (widget), dest_row)) {
-               priv->timer_expander = g_timeout_add (500, expand_row_timeout, widget);
-       }
-       gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), dest_row, pos);
-
-       /* Select the desired action. By default we pick MOVE */
-       suggested_action = GDK_ACTION_MOVE;
-
-        if (context->actions == GDK_ACTION_COPY)
-            gdk_drag_status(context, GDK_ACTION_COPY, time);
-       else if (context->actions == GDK_ACTION_MOVE)
-            gdk_drag_status(context, GDK_ACTION_MOVE, time);
-       else if (context->actions & suggested_action)
-            gdk_drag_status(context, suggested_action, time);
-       else
-            gdk_drag_status(context, GDK_ACTION_DEFAULT, time);
-
- out:
-       if (folder)
-               g_object_unref (folder);
-       if (dest_row) {
-               gtk_tree_path_free (dest_row);
-       }
-       g_signal_stop_emission_by_name (widget, "drag-motion");
-
-       return valid_location;
-}
-
-/*
- * This function sets the treeview as a source and a target for dnd
- * events. It also connects all the requirede signals.
- */
-static void
-setup_drag_and_drop (GtkTreeView *self)
-{
-       /* Set up the folder view as a dnd destination. Set only the
-          highlight flag, otherwise gtk will have a different
-          behaviour */
-#ifdef MODEST_TOOLKIT_HILDON2
-       return;
-#endif
-       gtk_drag_dest_set (GTK_WIDGET (self),
-                          GTK_DEST_DEFAULT_HIGHLIGHT,
-                          folder_view_drag_types,
-                          G_N_ELEMENTS (folder_view_drag_types),
-                          GDK_ACTION_MOVE | GDK_ACTION_COPY);
-
-       g_signal_connect (G_OBJECT (self),
-                         "drag_data_received",
-                         G_CALLBACK (on_drag_data_received),
-                         NULL);
-
-
-       /* Set up the treeview as a dnd source */
-       gtk_drag_source_set (GTK_WIDGET (self),
-                            GDK_BUTTON1_MASK,
-                            folder_view_drag_types,
-                            G_N_ELEMENTS (folder_view_drag_types),
-                            GDK_ACTION_MOVE | GDK_ACTION_COPY);
-
-       g_signal_connect (G_OBJECT (self),
-                         "drag_motion",
-                         G_CALLBACK (on_drag_motion),
-                         NULL);
-
-       g_signal_connect (G_OBJECT (self),
-                         "drag_data_get",
-                         G_CALLBACK (on_drag_data_get),
-                         NULL);
-
-       g_signal_connect (G_OBJECT (self),
-                         "drag_drop",
-                         G_CALLBACK (drag_drop_cb),
-                         NULL);
-}
-
-/*
- * This function manages the navigation through the folders using the
- * keyboard or the hardware keys in the device
- */
-static gboolean
-on_key_pressed (GtkWidget *self,
-               GdkEventKey *event,
-               gpointer user_data)
-{
-       GtkTreeSelection *selection;
-       GtkTreeIter iter;
-       GtkTreeModel *model;
-       gboolean retval = FALSE;
-
-       /* Up and Down are automatically managed by the treeview */
-       if (event->keyval == GDK_Return) {
-               /* Expand/Collapse the selected row */
-               selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
-               if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-                       GtkTreePath *path;
-
-                       path = gtk_tree_model_get_path (model, &iter);
-
-                       if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (self), path))
-                               gtk_tree_view_collapse_row (GTK_TREE_VIEW (self), path);
-                       else
-                               gtk_tree_view_expand_row (GTK_TREE_VIEW (self), path, FALSE);
-                       gtk_tree_path_free (path);
-               }
-               /* No further processing */
-               retval = TRUE;
-       }
-
-       return retval;
-}
-
-/*
- * We listen to the changes in the local folder account name key,
- * because we want to show the right name in the view. The local
- * folder account name corresponds to the device name in the Maemo
- * version. We do this because we do not want to query gconf on each
- * tree view refresh. It's better to cache it and change whenever
- * necessary.
- */
-static void
-on_configuration_key_changed (ModestConf* conf,
-                             const gchar *key,
-                             ModestConfEvent event,
-                             ModestConfNotificationId id,
-                             ModestFolderView *self)
-{
-       ModestFolderViewPrivate *priv;
-
-
-       g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
-       priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self);
-
-       if (!strcmp (key, MODEST_CONF_DEVICE_NAME)) {
-               g_free (priv->local_account_name);
-
-               if (event == MODEST_CONF_EVENT_KEY_UNSET)
-                       priv->local_account_name = g_strdup (MODEST_LOCAL_FOLDERS_DEFAULT_DISPLAY_NAME);
-               else
-                       priv->local_account_name = modest_conf_get_string (modest_runtime_get_conf(),
-                                                                          MODEST_CONF_DEVICE_NAME, NULL);
-
-               /* Force a redraw */
-#if GTK_CHECK_VERSION(2, 8, 0)
-               GtkTreeViewColumn * tree_column;
+               /* Force a redraw */
+#if GTK_CHECK_VERSION(2, 8, 0)
+               GtkTreeViewColumn * tree_column;
 
                tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (self),
                                                        NAME_COLUMN);
@@ -2962,10 +2858,18 @@ modest_folder_view_set_account_id_of_visible_server_account (ModestFolderView *s
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
        if (GTK_IS_TREE_MODEL_FILTER (model))
                gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model));
+       else
+               modest_folder_view_update_model(self,
+                                               (TnyAccountStore *) modest_runtime_get_account_store());
 
        /* Save settings to gconf */
        modest_widget_memory_save (modest_runtime_get_conf (), G_OBJECT(self),
                                   MODEST_CONF_FOLDER_VIEW_KEY);
+
+       /* Notify observers */
+       g_signal_emit (G_OBJECT(self),
+                      signals[VISIBLE_ACCOUNT_CHANGED_SIGNAL], 0,
+                      account_id);
 }
 
 const gchar *
@@ -2980,76 +2884,6 @@ modest_folder_view_get_account_id_of_visible_server_account (ModestFolderView *s
        return (const gchar *) priv->visible_account_id;
 }
 
-static gboolean
-find_inbox_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *inbox_iter)
-{
-       do {
-               GtkTreeIter child;
-               TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
-
-               gtk_tree_model_get (model, iter,
-                                   TYPE_COLUMN,
-                                   &type, -1);
-
-               gboolean result = FALSE;
-               if (type == TNY_FOLDER_TYPE_INBOX) {
-                       result = TRUE;
-               }
-               if (result) {
-                       *inbox_iter = *iter;
-                       return TRUE;
-               }
-
-               if (gtk_tree_model_iter_children (model, &child, iter)) {
-                       if (find_inbox_iter (model, &child, inbox_iter))
-                               return TRUE;
-               }
-
-       } while (gtk_tree_model_iter_next (model, iter));
-
-       return FALSE;
-}
-
-
-
-
-void
-modest_folder_view_select_first_inbox_or_local (ModestFolderView *self)
-{
-       GtkTreeModel *model;
-       GtkTreeIter iter, inbox_iter;
-       GtkTreeSelection *sel;
-       GtkTreePath *path = NULL;
-
-       g_return_if_fail (self && MODEST_IS_FOLDER_VIEW(self));
-
-       model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
-       if (!model)
-               return;
-
-       expand_root_items (self);
-       sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
-
-       if (!gtk_tree_model_get_iter_first (model, &iter)) {
-               g_warning ("%s: model is empty", __FUNCTION__);
-               return;
-       }
-
-       if (find_inbox_iter (model, &iter, &inbox_iter))
-               path = gtk_tree_model_get_path (model, &inbox_iter);
-       else
-               path = gtk_tree_path_new_first ();
-
-       /* Select the row and free */
-       gtk_tree_view_set_cursor (GTK_TREE_VIEW (self), path, NULL, FALSE);
-       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (self), path, NULL, FALSE, 0.0, 0.0);
-       gtk_tree_path_free (path);
-
-       /* set focus */
-       gtk_widget_grab_focus (GTK_WIDGET(self));
-}
-
-
 /* recursive */
 static gboolean
 find_folder_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *folder_iter,
@@ -3085,62 +2919,6 @@ find_folder_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *folder_it
        return FALSE;
 }
 
-#ifndef MODEST_TOOLKIT_HILDON2
-static void
-on_row_inserted_maybe_select_folder (GtkTreeModel *tree_model,
-                                    GtkTreePath *path,
-                                    GtkTreeIter *iter,
-                                    ModestFolderView *self)
-{
-       ModestFolderViewPrivate *priv = NULL;
-       GtkTreeSelection *sel;
-       TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
-       GObject *instance = NULL;
-
-       if (!MODEST_IS_FOLDER_VIEW(self))
-               return;
-
-       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
-
-       priv->reexpand = TRUE;
-
-       gtk_tree_model_get (tree_model, iter,
-                           TYPE_COLUMN, &type,
-                           INSTANCE_COLUMN, &instance,
-                           -1);
-
-       if (!instance)
-               return;
-
-       if (type == TNY_FOLDER_TYPE_INBOX && priv->folder_to_select == NULL) {
-               priv->folder_to_select = g_object_ref (instance);
-       }
-       g_object_unref (instance);
-
-       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);
-                       gtk_tree_view_set_cursor (GTK_TREE_VIEW(self), path, NULL, FALSE);
-
-                       gtk_tree_path_free (path);
-               }
-
-               /* Disable next */
-               modest_folder_view_disable_next_folder_selection (self);
-
-               /* Refilter the model */
-               gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (tree_model));
-       }
-}
-#endif
 
 void
 modest_folder_view_disable_next_folder_selection (ModestFolderView *self)
@@ -3259,11 +3037,23 @@ modest_folder_view_copy_model (ModestFolderView *folder_view_src,
        GtkTreeModel *filter_model = NULL;
        GtkTreeModel *model = NULL;
        GtkTreeModel *new_filter_model = NULL;
+       GtkTreeModel *old_tny_model = NULL;
+       GtkTreeModel *new_tny_model = NULL;
+       ModestFolderViewPrivate *dst_priv;
 
        g_return_if_fail (folder_view_src && MODEST_IS_FOLDER_VIEW (folder_view_src));
        g_return_if_fail (folder_view_dst && MODEST_IS_FOLDER_VIEW (folder_view_dst));
 
+       dst_priv = MODEST_FOLDER_VIEW_GET_PRIVATE (folder_view_dst);
+       if (!get_inner_models (folder_view_src, NULL, NULL, &new_tny_model))
+               new_tny_model = NULL;
+
        /* Get src model*/
+       if (get_inner_models (folder_view_dst, NULL, NULL, &old_tny_model)) {
+               modest_signal_mgr_disconnect (dst_priv->signal_handlers,
+                                             G_OBJECT (old_tny_model),
+                                             "activity-changed");
+       }
        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));
 
@@ -3273,12 +3063,18 @@ modest_folder_view_copy_model (ModestFolderView *folder_view_src,
                                                filter_row,
                                                folder_view_dst,
                                                NULL);
+
+
+
        /* Set copied model */
        gtk_tree_view_set_model (GTK_TREE_VIEW (folder_view_dst), new_filter_model);
-#ifndef MODEST_TOOLKIT_HILDON2
-       g_signal_connect (G_OBJECT(new_filter_model), "row-inserted",
-                         (GCallback) on_row_inserted_maybe_select_folder, folder_view_dst);
-#endif
+       if (new_tny_model) {
+               dst_priv->signal_handlers = modest_signal_mgr_connect (dst_priv->signal_handlers,
+                                                                      G_OBJECT (new_tny_model),
+                                                                      "activity-changed",
+                                                                      G_CALLBACK (on_activity_changed),
+                                                                      folder_view_dst);
+       }
 
        /* Free */
        g_object_unref (new_filter_model);
@@ -3305,6 +3101,22 @@ modest_folder_view_show_non_move_folders (ModestFolderView *folder_view,
        }
 }
 
+void
+modest_folder_view_show_message_count (ModestFolderView *folder_view,
+                                         gboolean show)
+{
+       ModestFolderViewPrivate* priv;
+
+       g_return_if_fail (folder_view && MODEST_IS_FOLDER_VIEW (folder_view));
+
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE(folder_view);
+       priv->show_message_count = show;
+
+       g_object_set (G_OBJECT (priv->messages_renderer),
+                     "visible", (priv->cell_style == MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT && priv->show_message_count),
+                     NULL);
+}
+
 /* Returns FALSE if it did not selected anything */
 static gboolean
 _clipboard_set_selected_data (ModestFolderView *folder_view,
@@ -3383,7 +3195,7 @@ modest_folder_view_set_cell_style (ModestFolderView *self,
        priv->cell_style = cell_style;
 
        g_object_set (G_OBJECT (priv->messages_renderer),
-                     "visible", (cell_style == MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT),
+                     "visible", (cell_style == MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT && priv->show_message_count),
                      NULL);
        
        gtk_widget_queue_draw (GTK_WIDGET (self));
@@ -3393,19 +3205,47 @@ static void
 update_style (ModestFolderView *self)
 {
        ModestFolderViewPrivate *priv;
-       GdkColor style_color;
+       GdkColor style_color, style_active_color;
+       PangoAttrList *attr_list;
+       GtkStyle *style;
+       PangoAttribute *attr;
 
        g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
 
-       if (!gtk_style_lookup_color (GTK_WIDGET (self)->style, "SecondaryTextColor", &style_color)) {
+       /* Set color */
+
+       attr_list = pango_attr_list_new ();
+
+       if (!gtk_style_lookup_color (gtk_widget_get_style (GTK_WIDGET (self)), "SecondaryTextColor", &style_color)) {
                gdk_color_parse ("grey", &style_color);
        }
-
-       g_object_set (G_OBJECT (priv->messages_renderer),
-                     "foreground-gdk", &style_color,
-                     "foreground-set", TRUE,
-                     NULL);
+       attr = pango_attr_foreground_new (style_color.red, style_color.green, style_color.blue);
+       pango_attr_list_insert (attr_list, attr);
+       
+       /* set font */
+       style = gtk_rc_get_style_by_paths (gtk_widget_get_settings
+                                          (GTK_WIDGET(self)),
+                                          "SmallSystemFont", NULL,
+                                          G_TYPE_NONE);
+       if (style) {
+               attr = pango_attr_font_desc_new (pango_font_description_copy
+                                                (style->font_desc));
+               pango_attr_list_insert (attr_list, attr);
+
+               g_object_set (G_OBJECT (priv->messages_renderer),
+                             "foreground-gdk", &style_color,
+                             "foreground-set", TRUE,
+                             "attributes", attr_list,
+                             NULL);
+               pango_attr_list_unref (attr_list);
+       }
+
+       if (gtk_style_lookup_color (gtk_widget_get_style (GTK_WIDGET (self)), "ActiveTextColor", &style_active_color)) {
+               priv->active_color = style_active_color;
+       } else {
+               gdk_color_parse ("000", &(priv->active_color));
+       }
 }
 
 static void 
@@ -3427,10 +3267,159 @@ modest_folder_view_set_filter (ModestFolderView *self,
        g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
 
-       priv->filter = filter;
+       priv->filter |= filter;
+
+       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+       if (GTK_IS_TREE_MODEL_FILTER(filter_model)) {
+               gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));  
+       }
+}
+
+void 
+modest_folder_view_unset_filter (ModestFolderView *self,
+                                ModestFolderViewFilter filter)
+{
+       ModestFolderViewPrivate *priv;
+       GtkTreeModel *filter_model;
+
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       priv->filter &= ~filter;
 
        filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
        if (GTK_IS_TREE_MODEL_FILTER(filter_model)) {
                gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));  
        }
 }
+
+gboolean
+modest_folder_view_any_folder_fulfils_rules (ModestFolderView *self,
+                                            ModestTnyFolderRules rules)
+{
+       GtkTreeModel *filter_model;
+       GtkTreeIter iter;
+       gboolean fulfil = FALSE;
+
+       if (!get_inner_models (self, &filter_model, NULL, NULL))
+               return FALSE;
+
+       if (!gtk_tree_model_get_iter_first (filter_model, &iter))
+               return FALSE;
+
+       do {
+               TnyFolderStore *folder;
+
+               gtk_tree_model_get (filter_model, &iter, INSTANCE_COLUMN, &folder, -1);
+               if (folder) {
+                       if (TNY_IS_FOLDER (folder)) {
+                               ModestTnyFolderRules folder_rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
+                               /* Folder rules are negative: non_writable, non_deletable... */
+                               if (!(folder_rules & rules))
+                                       fulfil = TRUE;
+                       }
+                       g_object_unref (folder);
+               }
+
+       } while (gtk_tree_model_iter_next (filter_model, &iter) && !fulfil);
+
+       return fulfil;
+}
+
+void 
+modest_folder_view_set_list_to_move (ModestFolderView *self,
+                                    TnyList *list)
+{
+       ModestFolderViewPrivate *priv;
+
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       if (priv->list_to_move)
+               g_object_unref (priv->list_to_move);
+
+       if (list)
+               g_object_ref (list);
+
+       priv->list_to_move = list;
+}
+
+void
+modest_folder_view_set_mailbox (ModestFolderView *self, const gchar *mailbox)
+{
+       ModestFolderViewPrivate *priv;
+
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       if (priv->mailbox)
+               g_free (priv->mailbox);
+
+       priv->mailbox = g_strdup (mailbox);
+
+       /* Notify observers */
+       g_signal_emit (G_OBJECT(self),
+                      signals[VISIBLE_ACCOUNT_CHANGED_SIGNAL], 0,
+                      priv->visible_account_id);
+}
+
+const gchar *
+modest_folder_view_get_mailbox (ModestFolderView *self)
+{
+       ModestFolderViewPrivate *priv;
+
+       g_return_val_if_fail (MODEST_IS_FOLDER_VIEW (self), NULL);
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       return (const gchar *) priv->mailbox;
+}
+
+gboolean 
+modest_folder_view_get_activity (ModestFolderView *self)
+{
+       ModestFolderViewPrivate *priv;
+       GtkTreeModel *inner_model;
+
+       g_return_val_if_fail (MODEST_IS_FOLDER_VIEW (self), FALSE);
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+       g_return_val_if_fail (get_inner_models (self, NULL, NULL, &inner_model), FALSE);
+
+       if (TNY_IS_GTK_FOLDER_LIST_STORE (inner_model)) {
+               return tny_gtk_folder_list_store_get_activity (TNY_GTK_FOLDER_LIST_STORE (inner_model));
+       } else {
+               return FALSE;
+       }
+}
+
+static void
+on_activity_changed (TnyGtkFolderListStore *store,
+                    gboolean activity,
+                    ModestFolderView *folder_view)
+{
+       ModestFolderViewPrivate *priv;
+
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (folder_view));
+       g_return_if_fail (TNY_IS_GTK_FOLDER_LIST_STORE (store));
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (folder_view);
+
+       g_signal_emit (G_OBJECT (folder_view), signals[ACTIVITY_CHANGED_SIGNAL], 0,
+                      activity);
+}
+
+TnyList *
+modest_folder_view_get_model_tny_list (ModestFolderView *self)
+{
+       GtkTreeModel *model;
+       TnyList *ret_value;
+
+       ret_value = NULL;
+       model = NULL;
+
+       if (get_inner_models (MODEST_FOLDER_VIEW (self), NULL, NULL, (GtkTreeModel **) &model)) {
+               ret_value = TNY_LIST (model);
+               g_object_ref (ret_value);
+       }
+
+       return ret_value;
+
+}