In ModestFolderView, use delayed refresh is we're trying to do real refresh.
[modest] / src / widgets / modest-folder-view.c
index 2fe6132..b748c30 100644 (file)
 #include <gdk/gdkkeysyms.h>
 #include <tny-account-store-view.h>
 #include <tny-gtk-account-list-model.h>
+#include <tny-gtk-folder-list-store.h>
 #include <tny-gtk-folder-store-tree-model.h>
 #include <tny-gtk-header-list-model.h>
+#include <tny-merge-folder.h>
 #include <tny-folder.h>
 #include <tny-folder-store-observer.h>
 #include <tny-account-store.h>
@@ -42,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>
@@ -57,7 +60,9 @@
 #include <modest-widget-memory.h>
 #include <modest-ui-actions.h>
 #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[] =
@@ -66,10 +71,33 @@ const GtkTargetEntry folder_view_drag_types[] =
        { GTK_TREE_PATH_AS_STRING_LIST, GTK_TARGET_SAME_APP, MODEST_HEADER_ROW }
 };
 
+/* 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);
@@ -80,6 +108,11 @@ static void         modest_folder_view_set_account_store (TnyAccountStoreView *s
 static void         on_selection_changed   (GtkTreeSelection *sel,
                                            gpointer data);
 
+static void         on_row_activated       (GtkTreeView *treeview,
+                                           GtkTreePath *path,
+                                           GtkTreeViewColumn *column,
+                                           gpointer userdata);
+
 static void         on_account_removed     (TnyAccountStore *self,
                                            TnyAccount *account,
                                            gpointer user_data);
@@ -146,18 +179,37 @@ static gboolean     _clipboard_set_selected_data (ModestFolderView *folder_view,
 
 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);
+#ifdef MODEST_TOOLKIT_HILDON2
+static void on_activity_changed (TnyGtkFolderListStore *store,
+                                gboolean activity,
+                                ModestFolderView *folder_view);
+#endif
 
 enum {
        FOLDER_SELECTION_CHANGED_SIGNAL,
        FOLDER_DISPLAY_NAME_CHANGED_SIGNAL,
+       FOLDER_ACTIVATED_SIGNAL,
+       VISIBLE_ACCOUNT_CHANGED_SIGNAL,
+       ACTIVITY_CHANGED_SIGNAL,
        LAST_SIGNAL
 };
 
@@ -168,30 +220,34 @@ struct _ModestFolderViewPrivate {
 
        TnyFolder            *folder_to_select; /* folder to select after the next update */
 
-       gulong                changed_signal;
-       gulong                account_inserted_signal;
-       gulong                account_removed_signal;
-       gulong                account_changed_signal;
-       gulong                conf_key_signal;
-       gulong                display_name_changed_signal;
-
        /* not unref this object, its a singlenton */
        ModestEmailClipboard *clipboard;
 
        /* Filter tree model */
        gchar **hidding_ids;
        guint n_selected;
+       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;
+
+       GSList   *signal_handlers;
+       GdkColor active_color;
 };
 #define MODEST_FOLDER_VIEW_GET_PRIVATE(o)                      \
        (G_TYPE_INSTANCE_GET_PRIVATE((o),                       \
@@ -248,6 +304,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->finalize = modest_folder_view_dispose;
 
        g_type_class_add_private (gobject_class,
                                  sizeof(ModestFolderViewPrivate));
@@ -279,8 +336,84 @@ modest_folder_view_class_init (ModestFolderViewClass *klass)
                              g_cclosure_marshal_VOID__STRING,
                              G_TYPE_NONE, 1, G_TYPE_STRING);
 
+       signals[FOLDER_ACTIVATED_SIGNAL] =
+               g_signal_new ("folder_activated",
+                             G_TYPE_FROM_CLASS (gobject_class),
+                             G_SIGNAL_RUN_FIRST,
+                             G_STRUCT_OFFSET (ModestFolderViewClass,
+                                              folder_activated),
+                             NULL, NULL,
+                             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
+       gtk_rc_parse_string ("class \"ModestFolderView\" style \"fremantle-touchlist\"");
+       
+#endif
+
+}
+
+/* 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: */
@@ -303,7 +436,7 @@ on_model_foreach_set_name(GtkTreeModel *model, GtkTreePath *path,  GtkTreeIter *
        GObject *instance = NULL;
 
        gtk_tree_model_get (model, iter,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
+                           INSTANCE_COLUMN, &instance,
                            -1);
 
        if (!instance)
@@ -366,6 +499,131 @@ on_get_mmc_account_name (TnyStoreAccount* account, gpointer user_data)
 }
 
 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;
+               }
+       }
+
+       last_separator = g_strrstr (*item_name, MODEST_FOLDER_PATH_SEPARATOR);
+       if (last_separator != NULL) {
+               last_separator = last_separator + strlen (MODEST_FOLDER_PATH_SEPARATOR);
+       }
+
+       if (n_parents > 0) {
+               GString *buffer;
+               gint i;
+
+               buffer = g_string_new ("");
+               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);
+               g_free (*item_name);
+               *item_name = g_string_free (buffer, FALSE);
+       }
+
+}
+
+static void
+format_compact_style (gchar **item_name,
+                     GObject *instance,
+                     const gchar *mailbox,
+                     gboolean bold,
+                     gboolean multiaccount,
+                     gboolean *use_markup)
+{
+       TnyFolder *folder;
+       gboolean is_special;
+       TnyFolderType folder_type;
+
+       if (!TNY_IS_FOLDER (instance))
+               return;
+
+       folder = (TnyFolder *) instance;
+
+       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;
+
+                       new_item_name = g_strdup (*item_name + strlen (prefix));
+                       if (!g_ascii_strcasecmp (new_item_name, "Inbox")) {
+                               g_free (new_item_name);
+                               new_item_name = g_strdup (_("mcen_me_folder_inbox"));
+                       }
+                       g_free (*item_name);
+                       *item_name = new_item_name;
+               }
+       } else if (!g_ascii_strcasecmp (*item_name, "Inbox")) {
+
+               g_free (*item_name);
+               *item_name = g_strdup (_("mcen_me_folder_inbox"));
+       }
+
+       if (!is_special || multiaccount) {
+               TnyAccount *account = tny_folder_get_account (folder);
+               const gchar *folder_name;
+               gboolean concat_folder_name = FALSE;
+               GString *buffer;
+
+               /* Should not happen */
+               if (account == NULL)
+                       return;
+
+               /* convert parent folders to dots */
+               convert_parent_folders_to_dots  (item_name);
+
+               folder_name = tny_folder_get_name (folder);
+               if (g_str_has_suffix (*item_name, folder_name)) {
+                       gchar *offset = g_strrstr (*item_name, folder_name);
+                       *offset = '\0';
+                       concat_folder_name = TRUE;
+               }
+
+               buffer = g_string_new ("");
+
+               buffer = g_string_append (buffer, *item_name);
+               if (concat_folder_name) {
+                       buffer = g_string_append (buffer, folder_name);
+               }
+               g_free (*item_name);
+               g_object_unref (account);
+
+               *item_name = g_string_free (buffer, FALSE);
+               *use_markup = FALSE;
+       } else {
+               *use_markup = FALSE;
+       }
+}
+
+static void
 text_cell_data  (GtkTreeViewColumn *column,
                 GtkCellRenderer *renderer,
                 GtkTreeModel *tree_model,
@@ -377,11 +635,12 @@ text_cell_data  (GtkTreeViewColumn *column,
        gchar *fname = NULL;
        TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
        GObject *instance = NULL;
+       gboolean use_markup = FALSE;
 
        gtk_tree_model_get (tree_model, iter,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &fname,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
+                           NAME_COLUMN, &fname,
+                           TYPE_COLUMN, &type,
+                           INSTANCE_COLUMN, &instance,
                            -1);
        if (!fname || !instance)
                goto end;
@@ -394,9 +653,13 @@ 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);
@@ -411,30 +674,41 @@ text_cell_data  (GtkTreeViewColumn *column,
                        }
                }
 
-               /* 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));
-               else
+                       drafts = TRUE;
+               } else {
                        number = tny_folder_get_unread_count (TNY_FOLDER(instance));
+                       drafts = FALSE;
+               }
 
-               /* Use bold font style if there are unread or unset messages */
-               if (number > 0) {
-                       if (type == TNY_FOLDER_TYPE_INBOX)
-                               item_name = g_strdup_printf ("%s (%d)", _("mcen_me_folder_inbox"), number);
-                       else
-                               item_name = g_strdup_printf ("%s (%d)", fname, number);
-                       item_weight = 800;
+               if (priv->cell_style == MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT) {
+                       item_name = g_strdup (fname);
+                       if (number > 0) {
+                               item_weight = 800;
+                       } else {
+                               item_weight = 400;
+                       }
                } else {
-                       if (type == TNY_FOLDER_TYPE_INBOX)
-                               item_name = g_strdup (_("mcen_me_folder_inbox"));
-                       else
+                       /* Use bold font style if there are unread or unset messages */
+                       if (number > 0) {
+                               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);
-                       item_weight = 400;
+                               item_weight = 400;
+                       }
                }
 
        } else if (TNY_IS_ACCOUNT (instance)) {
@@ -458,9 +732,34 @@ text_cell_data  (GtkTreeViewColumn *column,
        if (!item_name)
                item_name = g_strdup ("unknown");
 
+       if (priv->cell_style == MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT) {
+               gboolean multiaccount;
+
+               multiaccount = (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
+               /* Convert item_name to markup */
+               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: */
-               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? */
@@ -497,6 +796,88 @@ text_cell_data  (GtkTreeViewColumn *column,
                g_free (fname);
 }
 
+static void
+messages_cell_data  (GtkTreeViewColumn *column,
+                GtkCellRenderer *renderer,
+                GtkTreeModel *tree_model,
+                GtkTreeIter *iter,
+                gpointer data)
+{
+       ModestFolderView *self; 
+       ModestFolderViewPrivate *priv;
+       GObject *rendobj = (GObject *) renderer;
+       TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
+       GObject *instance = NULL;
+       gchar *item_name = NULL;
+
+       gtk_tree_model_get (tree_model, iter,
+                           TYPE_COLUMN, &type,
+                           INSTANCE_COLUMN, &instance,
+                           -1);
+       if (!instance)
+               goto end;
+
+       self = MODEST_FOLDER_VIEW (data);
+       priv =  MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+
+       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 (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
+                          NORMAL, like some versions of Dovecot */
+                       if (type == TNY_FOLDER_TYPE_NORMAL ||
+                           type == TNY_FOLDER_TYPE_UNKNOWN) {
+                               type = modest_tny_folder_guess_folder_type (TNY_FOLDER (instance));
+                       }
+               }
+
+               /* 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 {
+                       number = tny_folder_get_unread_count (TNY_FOLDER(instance));
+                       drafts = FALSE;
+               }
+
+               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 ("");
+
+       if (item_name) {
+               /* Set the name in the treeview cell: */
+               g_object_set (rendobj,"text", item_name, NULL);
+
+               g_free (item_name);
+
+       }
+
+ end:
+       if (instance)
+               g_object_unref (G_OBJECT (instance));
+}
+
 
 typedef struct {
        GdkPixbuf *pixbuf;
@@ -534,17 +915,24 @@ get_composite_icons (const gchar *icon_code,
 {
        ThreePixbufs *retval;
 
-       if (!*pixbuf)
-               *pixbuf = gdk_pixbuf_copy (modest_platform_get_icon (icon_code, MODEST_ICON_SIZE_SMALL));
+       if (!*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 && *pixbuf)
                *pixbuf_open = get_composite_pixbuf ("qgn_list_gene_fldr_exp",
-                                                    MODEST_ICON_SIZE_SMALL,
+                                                    FOLDER_ICON_SIZE,
                                                     *pixbuf);
 
-       if (!*pixbuf_close)
+       if (!*pixbuf_close && pixbuf && *pixbuf)
                *pixbuf_close = get_composite_pixbuf ("qgn_list_gene_fldr_clp",
-                                                     MODEST_ICON_SIZE_SMALL,
+                                                     FOLDER_ICON_SIZE,
                                                      *pixbuf);
 
        retval = g_slice_new0 (ThreePixbufs);
@@ -558,29 +946,81 @@ get_composite_icons (const gchar *icon_code,
        return retval;
 }
 
-static ThreePixbufs*
-get_folder_icons (TnyFolderType type, GObject *instance)
+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 (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 ||
@@ -588,7 +1028,33 @@ 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))) {
+#ifdef MODEST_TOOLKIT_HILDON2
+               return get_composite_icons (MODEST_FOLDER_ICON_REMOTE_FOLDER,
+                                           &anorm_pixbuf,
+                                           &anorm_pixbuf_open,
+                                           &anorm_pixbuf_close);
+#else
+               return get_composite_icons (MODEST_FOLDER_ICON_NORMAL,
+                                           &normal_pixbuf,
+                                           &normal_pixbuf_open,
+                                           &normal_pixbuf_close);
+#endif
+       }
+
        switch (type) {
+
        case TNY_FOLDER_TYPE_INVALID:
                g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
                break;
@@ -654,12 +1120,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:
-               retval = get_composite_icons (MODEST_FOLDER_ICON_NORMAL,
-                                             &normal_pixbuf,
-                                             &normal_pixbuf_open,
-                                             &normal_pixbuf_close);
+               /* Memory card folders could have an special icon */
+               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;
        }
 
@@ -689,19 +1169,20 @@ icon_cell_data  (GtkTreeViewColumn *column,
        TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
        gboolean has_children;
        ThreePixbufs *pixbufs;
+       ModestFolderView *folder_view = (ModestFolderView *) data;
 
        rendobj = (GObject *) renderer;
 
        gtk_tree_model_get (tree_model, iter,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
+                           TYPE_COLUMN, &type,
+                           INSTANCE_COLUMN, &instance,
                            -1);
 
        if (!instance)
                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 */
@@ -721,23 +1202,57 @@ add_columns (GtkWidget *treeview)
        GtkTreeViewColumn *column;
        GtkCellRenderer *renderer;
        GtkTreeSelection *sel;
+       ModestFolderViewPrivate *priv;
+
+       priv =  MODEST_FOLDER_VIEW_GET_PRIVATE(treeview);
 
        /* Create column */
        column = gtk_tree_view_column_new ();
 
        /* Set icon and text render function */
        renderer = gtk_cell_renderer_pixbuf_new();
+#ifdef MODEST_TOOLKIT_HILDON2
+       g_object_set (renderer,
+                     "xpad", MODEST_MARGIN_DEFAULT,
+                     "ypad", MODEST_MARGIN_DEFAULT,
+                     NULL);
+#endif
        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, "ellipsize", PANGO_ELLIPSIZE_END,
-                       "ellipsize-set", TRUE, NULL);
+       g_object_set (renderer, 
+#ifdef MODEST_TOOLKIT_HILDON2
+                     "ellipsize", PANGO_ELLIPSIZE_MIDDLE,
+                     "ypad", MODEST_MARGIN_DEFAULT,
+                     "xpad", MODEST_MARGIN_DEFAULT,
+#else
+                     "ellipsize", PANGO_ELLIPSIZE_END,
+#endif
+                     "ellipsize-set", TRUE, NULL);
        gtk_tree_view_column_pack_start (column, renderer, TRUE);
        gtk_tree_view_column_set_cell_data_func(column, renderer,
                                                text_cell_data, treeview, NULL);
 
+       priv->messages_renderer = gtk_cell_renderer_text_new ();
+       g_object_set (priv->messages_renderer, 
+#ifdef MODEST_TOOLKIT_HILDON2
+                     "yalign", 0.5,
+                     "ypad", MODEST_MARGIN_DEFAULT,
+                     "xpad", MODEST_MARGIN_DOUBLE,
+#else
+                     "scale", PANGO_SCALE_X_SMALL,
+                     "scale-set", TRUE,
+#endif
+                     "alignment", PANGO_ALIGN_RIGHT,
+                     "align-set", TRUE,
+                     "xalign", 1.0,
+                     NULL);
+       gtk_tree_view_column_pack_start (column, priv->messages_renderer, FALSE);
+       gtk_tree_view_column_set_cell_data_func(column, priv->messages_renderer,
+                                               messages_cell_data, treeview, NULL);
+
        /* Set selection mode */
        sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(treeview));
        gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
@@ -764,12 +1279,14 @@ 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->reexpand = TRUE;
+       priv->signal_handlers = 0;
 
        /* Initialize the local account name */
        conf = modest_runtime_get_conf();
@@ -779,8 +1296,11 @@ modest_folder_view_init (ModestFolderView *obj)
        priv->clipboard = modest_runtime_get_email_clipboard ();
        priv->hidding_ids = NULL;
        priv->n_selected = 0;
+       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));
@@ -789,24 +1309,32 @@ modest_folder_view_init (ModestFolderView *obj)
        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);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          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->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          (GObject*) 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);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT(conf),
+                                                          "key_changed",
+                                                          G_CALLBACK(on_configuration_key_changed),
+                                                          obj);
+
+       gdk_color_parse ("000", &priv->active_color);
+
+       update_style (obj);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT (obj), "notify::style",
+                                                          G_CALLBACK (on_notify_style), (gpointer) obj);
 }
 
 static void
@@ -818,38 +1346,26 @@ tny_account_store_view_init (gpointer g, gpointer iface_data)
 }
 
 static void
-modest_folder_view_finalize (GObject *obj)
+modest_folder_view_dispose (GObject *obj)
 {
+       static gboolean disposed = FALSE;
        ModestFolderViewPrivate *priv;
-       GtkTreeSelection    *sel;
 
-       g_return_if_fail (obj);
+       if (disposed)
+               return;
 
-       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;
-       }
+#ifdef MODEST_TOOLKIT_HILDON2
+       modest_signal_mgr_disconnect_all_and_destroy (priv->signal_handlers);
+#endif
 
+       /* Free external references */
        if (priv->account_store) {
-               g_signal_handler_disconnect (G_OBJECT(priv->account_store),
-                                            priv->account_inserted_signal);
-               g_signal_handler_disconnect (G_OBJECT(priv->account_store),
-                                            priv->account_removed_signal);
-               g_signal_handler_disconnect (G_OBJECT(priv->account_store),
-                                            priv->account_changed_signal);
                g_object_unref (G_OBJECT(priv->account_store));
                priv->account_store = NULL;
        }
 
-       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;
@@ -860,27 +1376,40 @@ modest_folder_view_finalize (GObject *obj)
                priv->folder_to_select = NULL;
        }
 
-       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);
-
-       if (priv->conf_key_signal) {
-               g_signal_handler_disconnect (modest_runtime_get_conf (),
-                                            priv->conf_key_signal);
-               priv->conf_key_signal = 0;
-       }
-
        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;
+       }
+}
+
+static void
+modest_folder_view_finalize (GObject *obj)
+{
+       ModestFolderViewPrivate *priv;
+
+       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;
+       }
+
+       g_free (priv->local_account_name);
+       g_free (priv->visible_account_id);
+       g_free (priv->mailbox);
+
        /* 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);
 }
 
@@ -899,34 +1428,40 @@ modest_folder_view_set_account_store (TnyAccountStoreView *self, TnyAccountStore
 
        if (G_UNLIKELY (priv->account_store)) {
 
-               if (g_signal_handler_is_connected (G_OBJECT (priv->account_store),
-                                                  priv->account_inserted_signal))
-                       g_signal_handler_disconnect (G_OBJECT (priv->account_store),
-                                                    priv->account_inserted_signal);
-               if (g_signal_handler_is_connected (G_OBJECT (priv->account_store),
-                                                  priv->account_removed_signal))
-                       g_signal_handler_disconnect (G_OBJECT (priv->account_store),
-                                                    priv->account_removed_signal);
-               if (g_signal_handler_is_connected (G_OBJECT (priv->account_store),
-                                                  priv->account_changed_signal))
-                       g_signal_handler_disconnect (G_OBJECT (priv->account_store),
-                                                    priv->account_changed_signal);
+               if (modest_signal_mgr_is_connected (priv->signal_handlers,
+                                                   G_OBJECT (priv->account_store),
+                                                   "account_inserted"))
+                       priv->signal_handlers = modest_signal_mgr_disconnect (priv->signal_handlers,
+                                                                             G_OBJECT (priv->account_store),
+                                                                             "account_inserted");
+               if (modest_signal_mgr_is_connected (priv->signal_handlers,
+                                                   G_OBJECT (priv->account_store),
+                                                   "account_removed"))
+                       priv->signal_handlers = modest_signal_mgr_disconnect (priv->signal_handlers,
+                                                                             G_OBJECT (priv->account_store),
+                                                                             "account_removed");
+               if (modest_signal_mgr_is_connected (priv->signal_handlers,
+                                                   G_OBJECT (priv->account_store),
+                                                   "account_changed"))
+                       priv->signal_handlers = modest_signal_mgr_disconnect (priv->signal_handlers,
+                                                                             G_OBJECT (priv->account_store),
+                                                                             "account_changed");
                g_object_unref (G_OBJECT (priv->account_store));
        }
 
        priv->account_store = g_object_ref (G_OBJECT (account_store));
 
-       priv->account_removed_signal =
-               g_signal_connect (G_OBJECT(account_store), "account_removed",
-                                 G_CALLBACK (on_account_removed), self);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT(account_store), "account_removed",
+                                                          G_CALLBACK (on_account_removed), self);
 
-       priv->account_inserted_signal =
-               g_signal_connect (G_OBJECT(account_store), "account_inserted",
-                                 G_CALLBACK (on_account_inserted), self);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT(account_store), "account_inserted",
+                                                          G_CALLBACK (on_account_inserted), self);
 
-       priv->account_changed_signal =
-               g_signal_connect (G_OBJECT(account_store), "account_changed",
-                                 G_CALLBACK (on_account_changed), self);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT(account_store), "account_changed",
+                                                          G_CALLBACK (on_account_changed), self);
 
        modest_folder_view_update_model (MODEST_FOLDER_VIEW (self), account_store);
        priv->reselect = FALSE;
@@ -936,12 +1471,34 @@ modest_folder_view_set_account_store (TnyAccountStoreView *self, TnyAccountStore
 }
 
 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 */
@@ -959,31 +1516,27 @@ 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__);
+       /* Get models */
+       if (!get_inner_models (MODEST_FOLDER_VIEW (user_data),
+                              &filter_model, NULL, &model))
                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__);
-               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->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                                  (GObject*) 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));
@@ -1041,7 +1594,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;
 
@@ -1050,26 +1603,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 */
@@ -1080,12 +1622,10 @@ 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));
@@ -1103,7 +1643,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;
 
@@ -1142,21 +1682,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 (modest_signal_mgr_is_connected (priv->signal_handlers, (GObject*) account, "outbox-deleted"))
+                       priv->signal_handlers = modest_signal_mgr_disconnect (priv->signal_handlers,
+                                                                             (GObject *) account,
+                                                                             "outbox-deleted");
        }
 
-       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 */
@@ -1165,6 +1705,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),
@@ -1236,21 +1777,40 @@ 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;
 
-       self = G_OBJECT (g_object_new (MODEST_TYPE_FOLDER_VIEW, NULL));
+       self = G_OBJECT (g_object_new (MODEST_TYPE_FOLDER_VIEW, 
+#ifdef MODEST_TOOLKIT_HILDON2
+                                      "hildon-ui-mode", HILDON_UI_MODE_NORMAL,
+#endif
+                                      NULL));
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
 
        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);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          (GObject*) sel, "changed",
+                                                          G_CALLBACK (on_selection_changed), self);
+
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          self, "row-activated",
+                                                          G_CALLBACK (on_row_activated), self);
 
-       g_signal_connect (self, "expose-event", G_CALLBACK (modest_folder_view_on_map), NULL);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          self, "expose-event", 
+                                                          G_CALLBACK (modest_folder_view_on_map), NULL);
 
        return GTK_WIDGET(self);
 }
@@ -1275,6 +1835,138 @@ expand_root_items (ModestFolderView *self)
        gtk_tree_path_free (path);
 }
 
+static gboolean
+is_parent_of (TnyFolder *a, TnyFolder *b)
+{
+       const gchar *a_id;
+       gboolean retval = FALSE;
+
+       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
@@ -1291,48 +1983,82 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
        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,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
+                           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 (type == TNY_FOLDER_TYPE_ROOT) {
-               /* TNY_FOLDER_TYPE_ROOT means that the instance is an
-                  account instead of a folder. */
-               if (TNY_IS_ACCOUNT (instance)) {
-                       TnyAccount *acc = TNY_ACCOUNT (instance);
-                       const gchar *account_id = tny_account_get_id (acc);
-
-                       /* If it isn't a special folder,
-                        * don't show it unless it is the visible account: */
-                       if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ONE &&
-                           !modest_tny_account_is_virtual_local_folders (acc) &&
-                           strcmp (account_id, MODEST_MMC_ACCOUNT_ID)) {
-
-                               /* Show only the visible account id */
-                               if (priv->visible_account_id) {
-                                       if (strcmp (account_id, priv->visible_account_id))
-                                               retval = FALSE;
-                               } else {
+       if (TNY_IS_ACCOUNT (instance)) {
+               TnyAccount *acc = TNY_ACCOUNT (instance);
+               const gchar *account_id = tny_account_get_id (acc);
+
+               /* If it isn't a special folder,
+                * don't show it unless it is the visible account: */
+               if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ONE &&
+                   !modest_tny_account_is_virtual_local_folders (acc) &&
+                   strcmp (account_id, MODEST_MMC_ACCOUNT_ID)) {
+
+                       /* Show only the visible account id */
+                       if (priv->visible_account_id) {
+                               if (strcmp (account_id, priv->visible_account_id))
                                        retval = FALSE;
+                       } else {
+                               retval = FALSE;
+                       }
+               }
+
+               /* Never show these to the user. They are merged into one folder
+                * in the local-folders account instead: */
+               if (retval && MODEST_IS_TNY_OUTBOX_ACCOUNT (acc))
+                       retval = FALSE;
+       } else {
+               if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ONE) {
+                       /* Only show special folders for current account if needed */
+                       if (TNY_IS_FOLDER (instance) && !TNY_IS_MERGE_FOLDER (instance)) {
+                               TnyAccount *account;
+
+                               account = tny_folder_get_account (TNY_FOLDER (instance));
+
+                               if (TNY_IS_ACCOUNT (account)) {
+                                       const gchar *account_id = tny_account_get_id (account);
+
+                                       if (!modest_tny_account_is_virtual_local_folders (account) &&
+                                           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;
+                                                 } 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);
                                }
                        }
 
-                       /* Never show these to the user. They are merged into one folder
-                        * in the local-folders account instead: */
-                       if (retval && MODEST_IS_TNY_OUTBOX_ACCOUNT (acc))
-                               retval = FALSE;
                }
        }
 
@@ -1348,11 +2074,17 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
                retval = !found;
        }
 
-
        /* If this is a move to dialog, hide Sent, Outbox and Drafts
        folder as no message can be move there according to UI specs */
-       if (!priv->show_non_move) {
-               switch (type) {
+       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:
@@ -1363,7 +2095,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)
@@ -1371,11 +2103,142 @@ 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_MESSAGE_ADD);
+               }
+       }
+
+       /* 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)) {
+                       /* Check folder rules */
+                       ModestTnyFolderRules rules;
+
+                       rules = modest_tny_folder_get_rules (TNY_FOLDER (instance));
+                       retval = !(rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE);
+               } else if (TNY_IS_ACCOUNT (instance)) {
+                       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 {
+                               guess_type = type;
+                       }
+
+                       switch (type) {
+                       case TNY_FOLDER_TYPE_OUTBOX:
+                       case TNY_FOLDER_TYPE_SENT:
+                       case TNY_FOLDER_TYPE_DRAFTS:
+                       case TNY_FOLDER_TYPE_ARCHIVE:
+                       case TNY_FOLDER_TYPE_INBOX:
+                               retval = FALSE;
+                               break;
+                       case TNY_FOLDER_TYPE_UNKNOWN:
+                       case TNY_FOLDER_TYPE_NORMAL:
+                               break;
+                       default:
+                               break;
+                       }
+
+               } else if (TNY_IS_ACCOUNT (instance)) {
+                       retval = FALSE;
+               }
+       }
+
+       if (retval && TNY_IS_FOLDER (instance)) {
+               rules = modest_tny_folder_get_rules (TNY_FOLDER (instance));
+       }
+
+       if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_DELETABLE)) {
+               if (TNY_IS_FOLDER (instance)) {
+                       retval = !(rules & MODEST_FOLDER_RULES_FOLDER_NON_DELETABLE);
+               } else if (TNY_IS_ACCOUNT (instance)) {
+                       retval = FALSE;
+               }
+       }
+
+       if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_RENAMEABLE)) {
+               if (TNY_IS_FOLDER (instance)) {
+                       retval = !(rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE);
+               } else if (TNY_IS_ACCOUNT (instance)) {
+                       retval = FALSE;
+               }
+       }
+
+       if (retval && (priv->filter & MODEST_FOLDER_VIEW_FILTER_MOVEABLE)) {
+               if (TNY_IS_FOLDER (instance)) {
+                       retval = !(rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE);
+               } else if (TNY_IS_ACCOUNT (instance)) {
+                       retval = FALSE;
                }
        }
 
        /* Free */
        g_object_unref (instance);
+        g_free (fname);
 
        return retval;
 }
@@ -1386,8 +2249,8 @@ modest_folder_view_update_model (ModestFolderView *self,
                                 TnyAccountStore *account_store)
 {
        ModestFolderViewPrivate *priv;
-       GtkTreeModel *model /* , *old_model */;
-       GtkTreeModel *filter_model = NULL, *sortable = NULL;
+       GtkTreeModel *model;
+       GtkTreeModel *filter_model = NULL, *sortable = NULL, *old_tny_model;
 
        g_return_val_if_fail (self && MODEST_IS_FOLDER_VIEW (self), FALSE);
        g_return_val_if_fail (account_store && MODEST_IS_TNY_ACCOUNT_STORE(account_store),
@@ -1406,7 +2269,45 @@ 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, 
+                                                         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
+
+       /* 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 (modest_signal_mgr_is_connected (priv->signal_handlers, (GObject *) account,
+                                                   "outbox-deleted"))
+                       priv->signal_handlers = modest_signal_mgr_disconnect (priv->signal_handlers,
+                                                                             (GObject *) account,
+                                                                             "outbox-deleted");
+
+               priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                                  (GObject*) account, "outbox-deleted",
+                                                                  G_CALLBACK (on_outbox_deleted_cb),
+                                                                  self);
+               g_object_unref (account);
+       }
 
        /* Get the accounts: */
        tny_account_store_get_accounts (TNY_ACCOUNT_STORE(account_store),
@@ -1415,10 +2316,10 @@ modest_folder_view_update_model (ModestFolderView *self,
 
        sortable = gtk_tree_model_sort_new_with_model (model);
        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sortable),
-                                             TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN,
+                                             NAME_COLUMN,
                                              GTK_SORT_ASCENDING);
        gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sortable),
-                                        TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN,
+                                        NAME_COLUMN,
                                         cmp_rows, NULL, NULL);
 
        /* Create filter model */
@@ -1428,10 +2329,29 @@ modest_folder_view_update_model (ModestFolderView *self,
                                                self,
                                                NULL);
 
+       if (get_inner_models (self, NULL, NULL, &old_tny_model)) {
+               if (modest_signal_mgr_is_connected (priv->signal_handlers, (GObject *) old_tny_model,
+                                                   "activity-changed"))
+                       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);
-       g_signal_connect (G_OBJECT(filter_model), "row-inserted",
-                         (GCallback) on_row_inserted_maybe_select_folder, self);
+#ifndef MODEST_TOOLKIT_HILDON2
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT(filter_model), "row-inserted",
+                                                          (GCallback) on_row_inserted_maybe_select_folder, self);
+#endif
+
+#ifdef MODEST_TOOLKIT_HILDON2
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT (model),
+                                                          "activity-changed",
+                                                          G_CALLBACK (on_activity_changed), 
+                                                          self);
+#endif
 
        g_object_unref (model);
        g_object_unref (filter_model);
@@ -1465,7 +2385,7 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
 
        if (selected) {
                gtk_tree_model_get (model, &iter,
-                                   TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &folder,
+                                   INSTANCE_COLUMN, &folder,
                                    -1);
 
                /* If the folder is the same do not notify */
@@ -1483,9 +2403,11 @@ 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 */
+#ifndef MODEST_TOOLKIT_HILDON2
                if (TNY_IS_FOLDER(priv->cur_folder_store))
                        tny_folder_sync_async (TNY_FOLDER(priv->cur_folder_store),
                                               FALSE, NULL, NULL, NULL);
+#endif
 
                g_signal_emit (G_OBJECT(tree_view), signals[FOLDER_SELECTION_CHANGED_SIGNAL], 0,
                       priv->cur_folder_store, FALSE);
@@ -1494,16 +2416,60 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
                priv->cur_folder_store = NULL;
        }
 
-       /* New current references */
-       priv->cur_folder_store = folder;
+       /* New current references */
+       priv->cur_folder_store = folder;
+
+       /* New folder has been selected. Do not notify if there is
+          nothing new selected */
+       if (selected) {
+               g_signal_emit (G_OBJECT(tree_view),
+                              signals[FOLDER_SELECTION_CHANGED_SIGNAL],
+                              0, priv->cur_folder_store, TRUE);
+       }
+}
+
+static void
+on_row_activated (GtkTreeView *treeview,
+                 GtkTreePath *treepath,
+                 GtkTreeViewColumn *column,
+                 gpointer user_data)
+{
+       GtkTreeModel *model = NULL;
+       TnyFolderStore *folder = NULL;
+       GtkTreeIter iter;
+       ModestFolderView *self = NULL;
+       ModestFolderViewPrivate *priv = NULL;
+
+       g_return_if_fail (treeview);
+       g_return_if_fail (user_data);
+
+       self = MODEST_FOLDER_VIEW (user_data);
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE(user_data);
+
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+
+       if (!gtk_tree_model_get_iter (model, &iter, treepath))
+               return;
 
-       /* New folder has been selected. Do not notify if there is
-          nothing new selected */
-       if (selected) {
-               g_signal_emit (G_OBJECT(tree_view),
-                              signals[FOLDER_SELECTION_CHANGED_SIGNAL],
-                              0, priv->cur_folder_store, TRUE);
+       gtk_tree_model_get (model, &iter,
+                           INSTANCE_COLUMN, &folder,
+                           -1);
+
+       g_signal_emit (G_OBJECT(self),
+                      signals[FOLDER_ACTIVATED_SIGNAL],
+                      0, folder);
+
+#ifdef MODEST_TOOLKIT_HILDON2
+       HildonUIMode ui_mode;
+       g_object_get (G_OBJECT (self), "hildon-ui-mode", &ui_mode, NULL);
+       if (ui_mode == HILDON_UI_MODE_NORMAL) {
+               if (priv->cur_folder_store)
+                       g_object_unref (priv->cur_folder_store);
+               priv->cur_folder_store = g_object_ref (folder);
        }
+#endif
+
+       g_object_unref (folder);
 }
 
 TnyFolderStore *
@@ -1544,30 +2510,196 @@ 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_subfolder_type_pos (TnyFolderType t)
+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;
        switch (t) {
        case TNY_FOLDER_TYPE_INBOX:
-               return 0;
-               break;
+       {
+               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 1;
+               return (TNY_IS_MERGE_FOLDER (folder_store))?2:4;
                break;
        case TNY_FOLDER_TYPE_DRAFTS:
-               return 2;
-               break;
+       {
+               account = tny_folder_get_account (folder_store);
+               is_special = (get_cmp_rows_type_pos (G_OBJECT (account)) == 1);
+               g_object_unref (account);
+               return is_special?1:4;
+       }
+       break;
        case TNY_FOLDER_TYPE_SENT:
-               return 3;
-               break;
+       {
+               account = tny_folder_get_account (folder_store);
+               is_special = (get_cmp_rows_type_pos (G_OBJECT (account)) == 1);
+               g_object_unref (account);
+               return is_special?3:4;
+       }
+       break;
        default:
                return 4;
        }
 }
 
+static gint
+compare_account_names (TnyAccount *a1, TnyAccount *a2)
+{
+       const gchar *a1_name, *a2_name;
+
+       a1_name = tny_account_get_name (a1);
+       a2_name = tny_account_get_name (a2);
+
+       return modest_text_utils_utf8_strcmp (a1_name, a2_name, TRUE);
+}
+
+static gint
+compare_accounts (TnyFolderStore *s1, TnyFolderStore *s2)
+{
+       TnyAccount *a1 = NULL, *a2 = NULL;
+       gint cmp;
+
+       if (TNY_IS_ACCOUNT (s1)) {
+               a1 = TNY_ACCOUNT (g_object_ref (s1));
+       } 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  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;
+       }
+       /* First we sort with the type of account */
+       cmp = get_cmp_rows_type_pos (G_OBJECT (a1)) - get_cmp_rows_type_pos (G_OBJECT (a2));
+       if (cmp != 0)
+               goto finish;
+
+       cmp = compare_account_names (a1, a2);
+
+finish:
+       if (a1)
+               g_object_unref (a1);
+       if (a2)
+               g_object_unref (a2);
+
+       return cmp;
+}
+
+static gint
+compare_accounts_first (TnyFolderStore *s1, TnyFolderStore *s2)
+{
+       gint is_account1, is_account2;
+
+       is_account1 = TNY_IS_ACCOUNT (s1)?1:0;
+       is_account2 = TNY_IS_ACCOUNT (s2)?1:0;
+
+       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
@@ -1587,14 +2719,14 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
        GObject *folder2 = NULL;
 
        gtk_tree_model_get (tree_model, iter1,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &name1,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &folder1,
+                           NAME_COLUMN, &name1,
+                           TYPE_COLUMN, &type,
+                           INSTANCE_COLUMN, &folder1,
                            -1);
        gtk_tree_model_get (tree_model, iter2,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &name2,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type2,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &folder2,
+                           NAME_COLUMN, &name2,
+                           TYPE_COLUMN, &type2,
+                           INSTANCE_COLUMN, &folder2,
                            -1);
 
        /* Return if we get no folder. This could happen when folder
@@ -1604,90 +2736,27 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
        if (!folder1 || !folder2)
                goto finish;
 
-       if (type == TNY_FOLDER_TYPE_ROOT) {
-               /* Compare the types, so that
-                * Remote accounts -> Local account -> MMC account .*/
-               const gint pos1 = get_cmp_rows_type_pos (folder1);
-               const gint pos2 = get_cmp_rows_type_pos (folder2);
-               /* printf ("DEBUG: %s:\n  type1=%s, pos1=%d\n  type2=%s, pos2=%d\n",
-                       __FUNCTION__, G_OBJECT_TYPE_NAME(folder1), pos1, G_OBJECT_TYPE_NAME(folder2), pos2); */
-               if (pos1 <  pos2)
-                       cmp = -1;
-               else if (pos1 > pos2)
-                       cmp = 1;
-               else {
-                       /* Compare items of the same type: */
-
-                       TnyAccount *account1 = NULL;
-                       if (TNY_IS_ACCOUNT (folder1))
-                               account1 = TNY_ACCOUNT (folder1);
-
-                       TnyAccount *account2 = NULL;
-                       if (TNY_IS_ACCOUNT (folder2))
-                               account2 = TNY_ACCOUNT (folder2);
-
-                       const gchar *account_id = account1 ? tny_account_get_id (account1) : NULL;
-                       const gchar *account_id2 = account2 ? tny_account_get_id (account2) : NULL;
-
-                       if (!account_id && !account_id2) {
-                               cmp = 0;
-                       } else if (!account_id) {
-                               cmp = -1;
-                       } else if (!account_id2) {
-                               cmp = +1;
-                       } else if (!strcmp (account_id, MODEST_MMC_ACCOUNT_ID)) {
-                               cmp = +1;
-                       } else {
-                               cmp = modest_text_utils_utf8_strcmp (name1, name2, TRUE);
-                       }
-               }
-       } else {
-               gint cmp1 = 0, cmp2 = 0;
-               /* get the parent to know if it's a local folder */
-
-               GtkTreeIter parent;
-               gboolean has_parent;
-               has_parent = gtk_tree_model_iter_parent (tree_model, &parent, iter1);
-               if (has_parent) {
-                       GObject *parent_folder;
-                       TnyFolderType parent_type = TNY_FOLDER_TYPE_UNKNOWN;
-                       gtk_tree_model_get (tree_model, &parent,
-                                           TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &parent_type,
-                                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &parent_folder,
-                                           -1);
-                       if ((parent_type == TNY_FOLDER_TYPE_ROOT) &&
-                           TNY_IS_ACCOUNT (parent_folder)) {
-                               if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent_folder))) {
-                                       cmp1 = get_cmp_subfolder_type_pos (modest_tny_folder_get_local_or_mmc_folder_type
-                                                                          (TNY_FOLDER (folder1)));
-                                       cmp2 = get_cmp_subfolder_type_pos (modest_tny_folder_get_local_or_mmc_folder_type
-                                                                          (TNY_FOLDER (folder2)));
-                               } else if (modest_tny_account_is_memory_card_account (TNY_ACCOUNT (parent_folder))) {
-                                       if (modest_local_folder_info_get_type (tny_folder_get_name (TNY_FOLDER (folder1))) == TNY_FOLDER_TYPE_ARCHIVE) {
-                                               cmp1 = 0;
-                                               cmp2 = 1;
-                                               } else if (modest_local_folder_info_get_type (tny_folder_get_name (TNY_FOLDER (folder2))) == TNY_FOLDER_TYPE_ARCHIVE) {
-                                               cmp1 = 1;
-                                               cmp2 = 0;
-                                       }
-                               }
-                       }
-                       g_object_unref (parent_folder);
-               }
-
-               /* if they are not local folders */
-               if (cmp1 == cmp2) {
-                       cmp1 = get_cmp_subfolder_type_pos (tny_folder_get_folder_type (TNY_FOLDER (folder1)));
-                       cmp2 = get_cmp_subfolder_type_pos (tny_folder_get_folder_type (TNY_FOLDER (folder2)));
-               }
+       /* Sort by type. First the special folders, then the archives */
+       cmp = get_cmp_pos (type, (TnyFolder *) folder1) - get_cmp_pos (type2, (TnyFolder *) folder2);
+       if (cmp != 0)
+               goto finish;
 
-               if (cmp1 == cmp2)
-                       cmp = modest_text_utils_utf8_strcmp (name1, name2, TRUE);
-               else
-                       cmp = (cmp1 - cmp2);
+       /* Now we sort using the account of each folder */
+       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;
        }
 
-finish:
+       /* Pure sort by name */
+       cmp = compare_folders (name1, name2);
+ finish:
        if (folder1)
                g_object_unref(G_OBJECT(folder1));
        if (folder2)
@@ -1765,7 +2834,7 @@ tree_path_to_folder (GtkTreeModel *model, GtkTreePath *path)
 
        if (gtk_tree_model_get_iter (model,&iter, path))
                gtk_tree_model_get (model, &iter,
-                                   TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &folder,
+                                   INSTANCE_COLUMN, &folder,
                                    -1);
        return folder;
 }
@@ -1833,7 +2902,7 @@ drag_and_drop_from_header_view (GtkTreeModel *source_model,
        /* Get the target folder */
        gtk_tree_model_get_iter (dest_model, &dest_iter, dest_row);
        gtk_tree_model_get (dest_model, &dest_iter,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
+                           INSTANCE_COLUMN,
                            &folder, -1);
 
        if (!folder || !TNY_IS_FOLDER(folder)) {
@@ -2041,11 +3110,11 @@ drag_and_drop_from_folder_view (GtkTreeModel     *source_model,
        /* Get data */
        gtk_tree_model_get_iter (dest_model, &dest_iter, dest_row);
        gtk_tree_model_get (dest_model, &dest_iter,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
+                           INSTANCE_COLUMN,
                            &dest_folder, -1);
        gtk_tree_model_get_iter (source_model, &iter, helper->source_row);
        gtk_tree_model_get (source_model, &iter,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
+                           INSTANCE_COLUMN,
                            &folder, -1);
 
        /* Create the info for the performer */
@@ -2332,16 +3401,22 @@ 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
+       ModestFolderViewPrivate *priv;
+
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
        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);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT (self), "drag_data_received",
+                                                          G_CALLBACK (on_drag_data_received), NULL);
 
 
        /* Set up the treeview as a dnd source */
@@ -2351,20 +3426,17 @@ setup_drag_and_drop (GtkTreeView *self)
                             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);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          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);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          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);
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT (self), "drag_drop",
+                                                          G_CALLBACK (drag_drop_cb), NULL);
 }
 
 /*
@@ -2438,7 +3510,7 @@ on_configuration_key_changed (ModestConf* conf,
                GtkTreeViewColumn * tree_column;
 
                tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (self),
-                                                       TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN);
+                                                       NAME_COLUMN);
                gtk_tree_view_column_queue_resize (tree_column);
 #else
                gtk_widget_queue_draw (GTK_WIDGET (self));
@@ -2490,6 +3562,11 @@ modest_folder_view_set_account_id_of_visible_server_account (ModestFolderView *s
        /* 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 *
@@ -2512,7 +3589,7 @@ find_inbox_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *inbox_iter
                TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
 
                gtk_tree_model_get (model, iter,
-                                   TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
+                                   TYPE_COLUMN,
                                    &type, -1);
 
                gboolean result = FALSE;
@@ -2540,6 +3617,7 @@ find_inbox_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *inbox_iter
 void
 modest_folder_view_select_first_inbox_or_local (ModestFolderView *self)
 {
+#ifndef MODEST_TOOLKIT_HILDON2
        GtkTreeModel *model;
        GtkTreeIter iter, inbox_iter;
        GtkTreeSelection *sel;
@@ -2571,6 +3649,7 @@ modest_folder_view_select_first_inbox_or_local (ModestFolderView *self)
 
        /* set focus */
        gtk_widget_grab_focus (GTK_WIDGET(self));
+#endif
 }
 
 
@@ -2586,9 +3665,9 @@ find_folder_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *folder_it
                gchar *name = NULL;
 
                gtk_tree_model_get (model, iter,
-                                   TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &a_folder,
-                                   TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &name,
-                                   TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
+                                   INSTANCE_COLUMN, &a_folder,
+                                   NAME_COLUMN, &name,
+                                   TYPE_COLUMN, &type,
                                    -1);
                g_free (name);
 
@@ -2609,7 +3688,7 @@ 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,
@@ -2629,9 +3708,13 @@ on_row_inserted_maybe_select_folder (GtkTreeModel *tree_model,
        priv->reexpand = TRUE;
 
        gtk_tree_model_get (tree_model, iter,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
+                           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);
        }
@@ -2660,7 +3743,7 @@ on_row_inserted_maybe_select_folder (GtkTreeModel *tree_model,
                gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (tree_model));
        }
 }
-
+#endif
 
 void
 modest_folder_view_disable_next_folder_selection (ModestFolderView *self)
@@ -2779,11 +3862,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));
 
@@ -2793,10 +3888,26 @@ 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);
-       g_signal_connect (G_OBJECT(new_filter_model), "row-inserted",
-                         (GCallback) on_row_inserted_maybe_select_folder, folder_view_dst);
+#ifndef MODEST_TOOLKIT_HILDON2
+       priv->signal_handlers = modest_signal_mgr_connect (priv->signal_handlers,
+                                                          G_OBJECT(new_filter_model), "row-inserted",
+                                                          (GCallback) on_row_inserted_maybe_select_folder,
+                                                          folder_view_dst);
+#endif
+#ifdef MODEST_TOOLKIT_HILDON2
+       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);
+       }
+#endif
 
        /* Free */
        g_object_unref (new_filter_model);
@@ -2823,6 +3934,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,
@@ -2882,9 +4009,233 @@ on_display_name_changed (ModestAccountMgr *mgr,
        GtkTreeViewColumn * tree_column;
 
        tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (self),
-                                               TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN);
+                                               NAME_COLUMN);
        gtk_tree_view_column_queue_resize (tree_column);
 #else
        gtk_widget_queue_draw (GTK_WIDGET (self));
 #endif
 }
+
+void 
+modest_folder_view_set_cell_style (ModestFolderView *self,
+                                  ModestFolderViewCellStyle cell_style)
+{
+       ModestFolderViewPrivate *priv = NULL;
+
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       priv->cell_style = cell_style;
+
+       g_object_set (G_OBJECT (priv->messages_renderer),
+                     "visible", (cell_style == MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT && priv->show_message_count),
+                     NULL);
+       
+       gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static void
+update_style (ModestFolderView *self)
+{
+       ModestFolderViewPrivate *priv;
+       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);
+
+       /* Set color */
+
+       attr_list = pango_attr_list_new ();
+       if (!gtk_style_lookup_color (GTK_WIDGET (self)->style, "SecondaryTextColor", &style_color)) {
+               gdk_color_parse ("grey", &style_color);
+       }
+       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 (self)->style, "ActiveTextColor", &style_active_color)) {
+               priv->active_color = style_active_color;
+       } else {
+               gdk_color_parse ("000", &(priv->active_color));
+       }
+}
+
+static void 
+on_notify_style (GObject *obj, GParamSpec *spec, gpointer userdata)
+{
+       if (strcmp ("style", spec->name) == 0) {
+               update_style (MODEST_FOLDER_VIEW (obj));
+               gtk_widget_queue_draw (GTK_WIDGET (obj));
+       } 
+}
+
+void 
+modest_folder_view_set_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));  
+       }
+}
+
+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;
+       }
+}
+
+#ifdef MODEST_TOOLKIT_HILDON2
+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);
+}
+#endif