Reconnecting after setting account settings
[modest] / src / widgets / modest-folder-view.c
index 0ef0b02..9297351 100644 (file)
@@ -41,6 +41,7 @@
 #include <tny-folder.h>
 #include <tny-camel-folder.h>
 #include <tny-simple-list.h>
+#include <tny-camel-account.h>
 #include <modest-tny-account.h>
 #include <modest-tny-folder.h>
 #include <modest-tny-local-folders-account.h>
@@ -124,7 +125,7 @@ static gboolean     on_drag_motion         (GtkWidget      *widget,
                                            guint           time,
                                            gpointer        user_data);
 
-static void expand_root_items (ModestFolderView *self);
+static void         expand_root_items (ModestFolderView *self);
 
 static gint         expand_row_timeout     (gpointer data);
 
@@ -177,6 +178,7 @@ struct _ModestFolderViewPrivate {
 
        gboolean  reselect; /* we use this to force a reselection of the INBOX */
        gboolean  show_non_move;
+       gboolean  reexpand; /* next time we expose, we'll expand all root folders */
 };
 #define MODEST_FOLDER_VIEW_GET_PRIVATE(o)                      \
        (G_TYPE_INSTANCE_GET_PRIVATE((o),                       \
@@ -263,7 +265,58 @@ modest_folder_view_class_init (ModestFolderViewClass *klass)
                              G_TYPE_NONE, 1, G_TYPE_STRING);
 }
 
+/* Simplify checks for NULLs: */
+static gboolean
+strings_are_equal (const gchar *a, const gchar *b)
+{
+       if (!a && !b)
+               return TRUE;
+       if (a && b)
+       {
+               return (strcmp (a, b) == 0);
+       }
+       else
+               return FALSE;
+}
 
+static gboolean
+on_model_foreach_set_name(GtkTreeModel *model, GtkTreePath *path,  GtkTreeIter *iter, gpointer data)
+{
+       GObject *instance = NULL;
+       
+       gtk_tree_model_get (model, iter,
+                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
+                           -1);
+                           
+       if (!instance)
+               return FALSE; /* keep walking */
+                       
+       if (!TNY_IS_ACCOUNT (instance)) {
+               g_object_unref (instance);
+               return FALSE; /* keep walking */        
+       }    
+       
+       /* Check if this is the looked-for account: */
+       TnyAccount *this_account = TNY_ACCOUNT (instance);
+       TnyAccount *account = TNY_ACCOUNT (data);
+       
+       const gchar *this_account_id = tny_account_get_id(this_account);
+       const gchar *account_id = tny_account_get_id(account);
+       g_object_unref (instance);
+       instance = NULL;
+
+       /* printf ("DEBUG: %s: this_account_id=%s, account_id=%s\n", __FUNCTION__, this_account_id, account_id); */
+       if (strings_are_equal(this_account_id, account_id)) {
+               /* Tell the model that the data has changed, so that
+                * it calls the cell_data_func callbacks again: */
+               /* TODO: This does not seem to actually cause the new string to be shown: */
+               gtk_tree_model_row_changed (model, path, iter);
+               
+               return TRUE; /* stop walking */
+       }
+       
+       return FALSE; /* keep walking */
+}
 
 typedef struct 
 {
@@ -271,6 +324,28 @@ typedef struct
        gchar *previous_name;
 } GetMmcAccountNameData;
 
+static void
+on_get_mmc_account_name (TnyStoreAccount* account, gpointer user_data)
+{
+       /* printf ("DEBU1G: %s: account name=%s\n", __FUNCTION__, tny_account_get_name (TNY_ACCOUNT(account))); */
+
+       GetMmcAccountNameData *data = (GetMmcAccountNameData*)user_data;
+       
+       if (!strings_are_equal (
+               tny_account_get_name(TNY_ACCOUNT(account)), 
+               data->previous_name)) {
+       
+               /* Tell the model that the data has changed, so that 
+                * it calls the cell_data_func callbacks again: */
+               ModestFolderView *self = data->self;
+               GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+               if (model)
+                       gtk_tree_model_foreach(model, on_model_foreach_set_name, account);
+       }
+
+       g_free (data->previous_name);
+       g_slice_free (GetMmcAccountNameData, data);
+}
 
 static void
 text_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
@@ -279,8 +354,6 @@ text_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
        ModestFolderViewPrivate *priv;
        GObject *rendobj;
        gchar *fname = NULL;
-       gint unread = 0;
-       gint all = 0;
        TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
        GObject *instance = NULL;
 
@@ -290,8 +363,6 @@ text_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
 
        gtk_tree_model_get (tree_model, iter,
                            TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, &fname,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_ALL_COLUMN, &all,
-                           TNY_GTK_FOLDER_STORE_TREE_MODEL_UNREAD_COLUMN, &unread,
                            TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
                            TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
                            -1);
@@ -323,12 +394,17 @@ text_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
                        }
                }
 
-               /* Select the number to show: the unread or unsent messages */
-               if ((type == TNY_FOLDER_TYPE_DRAFTS) || (type == TNY_FOLDER_TYPE_OUTBOX))
-                       number = all;
+               /* 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... */
+                       number = tny_folder_get_all_count (TNY_FOLDER(instance));
                else
-                       number = unread;
-               
+                       number = tny_folder_get_unread_count (TNY_FOLDER(instance));
+                                                               
                /* Use bold font style if there are unread or unset messages */
                if (number > 0) {
                        item_name = g_strdup_printf ("%s (%d)", fname, number);
@@ -375,7 +451,25 @@ text_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
                g_free (item_name);
                
        }
-                               
+       
+       /* If it is a Memory card account, make sure that we have the correct name.
+        * This function will be trigerred again when the name has been retrieved: */
+       if (TNY_IS_STORE_ACCOUNT (instance) && 
+               modest_tny_account_is_memory_card_account (TNY_ACCOUNT (instance))) {
+
+               /* Get the account name asynchronously: */
+               GetMmcAccountNameData *callback_data = 
+                       g_slice_new0(GetMmcAccountNameData);
+               callback_data->self = self;
+
+               const gchar *name = tny_account_get_name (TNY_ACCOUNT(instance));
+               if (name)
+                       callback_data->previous_name = g_strdup (name); 
+
+               modest_tny_account_get_mmc_account_name (TNY_STORE_ACCOUNT (instance), 
+                                                        on_get_mmc_account_name, callback_data);
+       }
+                       
        g_object_unref (G_OBJECT (instance));
        g_free (fname);
 }
@@ -389,7 +483,7 @@ icon_cell_data  (GtkTreeViewColumn *column,  GtkCellRenderer *renderer,
        TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
        const gchar *account_id = NULL;
        gboolean has_children;
-       
+
        rendobj = G_OBJECT(renderer);
        gtk_tree_model_get (tree_model, iter,
                            TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
@@ -544,6 +638,8 @@ modest_folder_view_init (ModestFolderView *obj)
        priv->visible_account_id = NULL;
        priv->folder_to_select = NULL;
 
+       priv->reexpand = TRUE;
+
        /* Initialize the local account name */
        conf = modest_runtime_get_conf();
        priv->local_account_name = modest_conf_get_string (conf, MODEST_CONF_DEVICE_NAME, NULL);
@@ -738,14 +834,37 @@ on_account_inserted (TnyAccountStore *account_store,
        /* Insert the account in the model */
        tny_list_append (TNY_LIST (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model))),
                         G_OBJECT (account));
+
 }
 
 
 static void
-on_account_changed (TnyAccountStore *account_store, TnyAccount *tny_account,
+on_account_changed (TnyAccountStore *account_store, 
+                   TnyAccount *tny_account,
                    gpointer user_data)
 {
        /* do nothing */
+       ModestFolderViewPrivate *priv;
+       GtkTreeModel *sort_model, *filter_model;
+
+       /* Ignore transport account insertions, we're not showing them
+          in the folder view */
+       if (TNY_IS_TRANSPORT_ACCOUNT (tny_account))
+               return;
+
+       priv = MODEST_FOLDER_VIEW_GET_PRIVATE (user_data);
+
+       /* Get the inner model */
+       filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_data));
+       sort_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model));
+       
+       /* 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));
+
+       /* 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));
 }
 
 
@@ -870,7 +989,10 @@ modest_folder_view_on_map (ModestFolderView *self,
                               NULL);
        }
 
-       expand_root_items (self); 
+       if (priv->reexpand) {
+               expand_root_items (self); 
+               priv->reexpand = FALSE;
+       }
 
        return FALSE;
 }
@@ -902,11 +1024,17 @@ static void
 expand_root_items (ModestFolderView *self)
 {
        GtkTreePath *path;
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
        path = gtk_tree_path_new_first ();
 
        /* all folders should have child items, so.. */
-       while (gtk_tree_view_expand_row (GTK_TREE_VIEW(self), path, FALSE))
+       do {
+               gtk_tree_view_expand_row (GTK_TREE_VIEW(self), path, FALSE);
                gtk_tree_path_next (path);
+       } while (gtk_tree_model_get_iter (model, &iter, path));
        
        gtk_tree_path_free (path);
 }
@@ -1108,8 +1236,6 @@ on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE(user_data);
 
        selected = gtk_tree_selection_get_selected (sel, &model, &iter);
-/*     if(!gtk_tree_selection_get_selected (sel, &model, &iter)) */
-/*             return; */
 
        /* Notify the display name observers */
        g_signal_emit (G_OBJECT(user_data),
@@ -2001,10 +2127,14 @@ on_configuration_key_changed (ModestConf* conf,
                                                                           MODEST_CONF_DEVICE_NAME, NULL);
 
                /* Force a redraw */
-#if GTK_CHECK_VERSION(2, 8, 0) /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
-               GtkTreeViewColumn * tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (self), 
-                                                                           TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN);
+#if GTK_CHECK_VERSION(2, 8, 0)
+               GtkTreeViewColumn * tree_column;
+
+               tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (self), 
+                                                       TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN);
                gtk_tree_view_column_queue_resize (tree_column);
+#else
+               gtk_widget_queue_draw (GTK_WIDGET (self));
 #endif
        }
 }
@@ -2121,6 +2251,7 @@ modest_folder_view_select_first_inbox_or_local (ModestFolderView *self)
 
        /* Select the row and free */
        gtk_tree_view_set_cursor (GTK_TREE_VIEW (self), path, NULL, FALSE);
+       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (self), path, NULL, FALSE, 0.0, 0.0);
        gtk_tree_path_free (path);
 
        /* set focus */
@@ -2170,11 +2301,25 @@ on_row_inserted_maybe_select_folder (GtkTreeModel *tree_model, GtkTreePath  *pat
 {
        ModestFolderViewPrivate *priv = NULL;
        GtkTreeSelection *sel;
+       TnyFolderType type = TNY_FOLDER_TYPE_UNKNOWN;
+       GObject *instance = NULL;
 
        if (!MODEST_IS_FOLDER_VIEW(self))
                return;
        
        priv = MODEST_FOLDER_VIEW_GET_PRIVATE (self);
+
+       priv->reexpand = TRUE;
+
+       gtk_tree_model_get (tree_model, iter, 
+                           TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN, &type,
+                           TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &instance,
+                           -1);
+       if (type == TNY_FOLDER_TYPE_INBOX && priv->folder_to_select == NULL) {
+               priv->folder_to_select = g_object_ref (instance);
+       }
+       g_object_unref (instance);
+
        
        if (priv->folder_to_select) {