Set attachments view links mode in fremantle for view
[modest] / src / widgets / modest-folder-view.c
index 14abcb5..0da3a04 100644 (file)
 #include <gdk/gdkkeysyms.h>
 #include <tny-account-store-view.h>
 #include <tny-gtk-account-list-model.h>
-#ifdef MODEST_TOOLKIT_HILDON2
 #include <tny-gtk-folder-list-store.h>
-#else
 #include <tny-gtk-folder-store-tree-model.h>
-#endif
 #include <tny-gtk-header-list-model.h>
 #include <tny-merge-folder.h>
 #include <tny-folder.h>
@@ -62,7 +59,7 @@
 #include <modest-widget-memory.h>
 #include <modest-ui-actions.h>
 #include "modest-dnd.h"
-#include <modest-ui-constants.h>
+#include "modest-ui-constants.h"
 #include "widgets/modest-window.h"
 
 /* Folder view drag types */
@@ -193,6 +190,11 @@ 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     get_inner_models        (ModestFolderView *self,
+                                            GtkTreeModel **filter_model,
+                                            GtkTreeModel **sort_model,
+                                            GtkTreeModel **tny_model);
+
 enum {
        FOLDER_SELECTION_CHANGED_SIGNAL,
        FOLDER_DISPLAY_NAME_CHANGED_SIGNAL,
@@ -235,6 +237,8 @@ struct _ModestFolderViewPrivate {
        gboolean  reexpand; /* next time we expose, we'll expand all root folders */
 
        GtkCellRenderer *messages_renderer;
+
+       gulong                outbox_deleted_handler;
 };
 #define MODEST_FOLDER_VIEW_GET_PRIVATE(o)                      \
        (G_TYPE_INSTANCE_GET_PRIVATE((o),                       \
@@ -341,6 +345,41 @@ modest_folder_view_class_init (ModestFolderViewClass *klass)
 
 }
 
+/* Retrieves the filter, sort and tny models of the folder view. If
+   any of these does not exist then it returns FALSE */
+static gboolean
+get_inner_models (ModestFolderView *self, 
+                 GtkTreeModel **filter_model,
+                 GtkTreeModel **sort_model,
+                 GtkTreeModel **tny_model)
+{
+       GtkTreeModel *s_model, *f_model, *t_model;
+
+       f_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+       if (!GTK_IS_TREE_MODEL_FILTER(f_model)) {
+               g_warning ("BUG: %s: not a valid filter model", __FUNCTION__);
+               return FALSE;
+       }
+
+       s_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (f_model));
+       if (!GTK_IS_TREE_MODEL_SORT(s_model)) {
+               g_warning ("BUG: %s: not a valid sort model", __FUNCTION__);
+               return FALSE;
+       }
+
+       t_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model));
+
+       /* Assign values */
+       if (filter_model)
+               *filter_model = f_model;
+       if (sort_model)
+               *sort_model = s_model;
+       if (tny_model)
+               *tny_model = t_model;
+
+       return TRUE;
+}
+
 /* Simplify checks for NULLs: */
 static gboolean
 strings_are_equal (const gchar *a, const gchar *b)
@@ -424,6 +463,42 @@ on_get_mmc_account_name (TnyStoreAccount* account, gpointer user_data)
 }
 
 static void
+convert_parent_folders_to_dots (gchar **item_name)
+{
+       gint n_parents = 0;
+       gchar *c;
+       gchar *last_separator;
+
+       if (item_name == NULL)
+               return;
+
+       for (c = *item_name; *c != '\0'; c++) {
+               if (g_str_has_prefix (c, MODEST_FOLDER_PATH_SEPARATOR)) {
+                       n_parents++;
+               }
+       }
+
+       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; 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,
                      gboolean bold,
@@ -452,6 +527,9 @@ format_compact_style (gchar **item_name,
                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);
@@ -460,8 +538,7 @@ format_compact_style (gchar **item_name,
                }
 
                buffer = g_string_new ("");
-               buffer = g_string_append (buffer, tny_account_get_name (account));
-               buffer = g_string_append (buffer, MODEST_FOLDER_PATH_SEPARATOR);
+
                buffer = g_string_append (buffer, *item_name);
                if (concat_folder_name) {
                        if (bold) buffer = g_string_append (buffer, "<span weight='bold'>");
@@ -777,25 +854,25 @@ get_composite_icons (const gchar *icon_code,
        return retval;
 }
 
-static ThreePixbufs*
+static inline ThreePixbufs*
 get_folder_icons (TnyFolderType type, GObject *instance)
 {
        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;
@@ -812,13 +889,21 @@ get_folder_icons (TnyFolderType type, GObject *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_ACCOUNT,
+                                           &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;
@@ -884,12 +969,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;
        }
 
@@ -1018,7 +1117,7 @@ modest_folder_view_init (ModestFolderView *obj)
        priv->cur_folder_store   = NULL;
        priv->visible_account_id = NULL;
        priv->folder_to_select = NULL;
-
+       priv->outbox_deleted_handler = 0;
        priv->reexpand = TRUE;
 
        /* Initialize the local account name */
@@ -1078,6 +1177,7 @@ modest_folder_view_finalize (GObject *obj)
 {
        ModestFolderViewPrivate *priv;
        GtkTreeSelection    *sel;
+       TnyAccount *local_account;
 
        g_return_if_fail (obj);
 
@@ -1088,6 +1188,16 @@ modest_folder_view_finalize (GObject *obj)
                priv->timer_expander = 0;
        }
 
+       local_account = (TnyAccount *)
+               modest_tny_account_store_get_local_folders_account (modest_runtime_get_account_store ());
+       if (local_account) {
+               if (g_signal_handler_is_connected (local_account,
+                                                  priv->outbox_deleted_handler))
+                       g_signal_handler_disconnect (local_account,
+                                                    priv->outbox_deleted_handler);
+               g_object_unref (local_account);
+       }
+
        if (priv->account_store) {
                g_signal_handler_disconnect (G_OBJECT(priv->account_store),
                                             priv->account_inserted_signal);
@@ -1192,12 +1302,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 */
@@ -1215,31 +1347,29 @@ on_account_inserted (TnyAccountStore *account_store,
                                              G_OBJECT (user_data),
                                              MODEST_CONF_FOLDER_VIEW_KEY);
 
-       if (!GTK_IS_TREE_VIEW(user_data)) {
-               g_warning ("BUG: %s: not a valid tree view", __FUNCTION__);
-               return;
-       }
-
-       /* Get the inner model */
-       /* check, is some rare cases, we did not get the right thing here,
-        * NB#84097 */
-       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
-       if (!GTK_IS_TREE_MODEL_FILTER(filter_model)) {
-               g_warning ("BUG: %s: not a valid filter model", __FUNCTION__);
-               return;
-       }
 
-       /* check, is some rare cases, we did not get the right thing here,
-        * NB#84097 */
-       sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
-       if (!GTK_IS_TREE_MODEL_SORT(sort_model)) {
-               g_warning ("BUG: %s: not a valid sort model", __FUNCTION__);
+       /* Get models */
+       if (!get_inner_models (MODEST_FOLDER_VIEW (user_data),
+                              &filter_model, NULL, &model))
                return;
-       }
 
        /* Insert the account in the model */
-       tny_list_append (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
-                        G_OBJECT (account));
+       tny_list_append (TNY_LIST (model), G_OBJECT (account));
+
+       /* When the model is a list store (plain representation) the
+          outbox is not a child of any account so we have to manually
+          delete it because removing the local folders account won't
+          delete it (because tny_folder_get_account() is not defined
+          for a merge folder */
+       if (TNY_IS_GTK_FOLDER_LIST_STORE (model) &&
+           MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (account)) {
+
+               priv->outbox_deleted_handler =
+                       g_signal_connect (account,
+                                         "outbox-deleted",
+                                         G_CALLBACK (on_outbox_deleted_cb),
+                                         user_data);
+       }
 
        /* Refilter the model */
        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
@@ -1297,7 +1427,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;
 
@@ -1306,26 +1436,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 */
@@ -1336,12 +1455,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));
@@ -1359,7 +1476,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;
 
@@ -1398,21 +1515,21 @@ on_account_removed (TnyAccountStore *account_store,
                g_object_unref (folder_to_select_account);
        }
 
-       /* Remove the account from the model */
-       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
-       if (!GTK_IS_TREE_MODEL_FILTER(filter_model)) {
-               g_warning ("BUG: %s: not a valid filter model", __FUNCTION__);
+       if (!get_inner_models (MODEST_FOLDER_VIEW (user_data),
+                              &filter_model, NULL, &model))
                return;
-       }
 
-       sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
-       if (!GTK_IS_TREE_MODEL_SORT(sort_model)) {
-               g_warning ("BUG: %s: not a valid sort model", __FUNCTION__);
-               return;
+       /* Disconnect the signal handler */
+       if (TNY_IS_GTK_FOLDER_LIST_STORE (model) &&
+           MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (account)) {
+               if (g_signal_handler_is_connected (account,
+                                                  priv->outbox_deleted_handler))
+                       g_signal_handler_disconnect (account,
+                                                    priv->outbox_deleted_handler);
        }
 
-       tny_list_remove (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
-                        G_OBJECT (account));
+       /* Remove the account from the model */
+       tny_list_remove (TNY_LIST (model), G_OBJECT (account));
 
        /* If the removed account is the currently viewed one then
           clear the configuration value. The new visible account will be the default account */
@@ -1553,6 +1670,7 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
        guint i;
        gboolean found = FALSE;
        gboolean cleared = FALSE;
+       ModestTnyFolderRules rules = 0;
 
        g_return_val_if_fail (MODEST_IS_FOLDER_VIEW (data), FALSE);
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (data);
@@ -1570,10 +1688,6 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
                return FALSE;
 
        if (TNY_IS_ACCOUNT (instance)) {
-#ifdef MODEST_TOOLKIT_HILDON2
-               /* In hildon 2.2 we don't show the account rows */
-               return FALSE;
-#else
                TnyAccount *acc = TNY_ACCOUNT (instance);
                const gchar *account_id = tny_account_get_id (acc);
 
@@ -1596,7 +1710,6 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
                 * in the local-folders account instead: */
                if (retval && MODEST_IS_TNY_OUTBOX_ACCOUNT (acc))
                        retval = FALSE;
-#endif
        } else {
                if (priv->style == MODEST_FOLDER_VIEW_STYLE_SHOW_ONE) {
                        /* Only show special folders for current account if needed */
@@ -1661,18 +1774,80 @@ filter_row (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
        }
 
        /* 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_CAN_HAVE_FOLDERS)) {
                if (TNY_IS_FOLDER (instance)) {
-                       TnyFolderCaps capabilities;
+                       /* Check folder rules */
+                       ModestTnyFolderRules rules;
 
-                       capabilities = tny_folder_get_caps (TNY_FOLDER (instance));
-                       retval = !(capabilities & TNY_FOLDER_CAPS_NOCHILDREN);
+                       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 (retval) {
-                               retval = ((type != TNY_FOLDER_TYPE_DRAFTS) &&
-                                         (type != TNY_FOLDER_TYPE_OUTBOX) &&
-                                         (type != TNY_FOLDER_TYPE_SENT));
+                       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;
                }
@@ -1719,6 +1894,31 @@ modest_folder_view_update_model (ModestFolderView *self,
        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 (g_signal_handler_is_connected (account,
+                                                  priv->outbox_deleted_handler))
+                       g_signal_handler_disconnect (account,
+                                                    priv->outbox_deleted_handler);
+
+               priv->outbox_deleted_handler =
+                       g_signal_connect (account,
+                                         "outbox-deleted",
+                                         G_CALLBACK (on_outbox_deleted_cb),
+                                         self);
+               g_object_unref (account);
+       }
+
        /* Get the accounts: */
        tny_account_store_get_accounts (TNY_ACCOUNT_STORE(account_store),
                                        TNY_LIST (model),
@@ -3322,7 +3522,25 @@ modest_folder_view_set_filter (ModestFolderView *self,
        g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
 
-       priv->filter = filter;
+       priv->filter |= filter;
+
+       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+       if (GTK_IS_TREE_MODEL_FILTER(filter_model)) {
+               gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));  
+       }
+}
+
+void 
+modest_folder_view_unset_filter (ModestFolderView *self,
+                                ModestFolderViewFilter filter)
+{
+       ModestFolderViewPrivate *priv;
+       GtkTreeModel *filter_model;
+
+       g_return_if_fail (MODEST_IS_FOLDER_VIEW (self));
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       priv->filter &= ~filter;
 
        filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
        if (GTK_IS_TREE_MODEL_FILTER(filter_model)) {