* Fixes NB#57398
[modest] / src / widgets / modest-header-view.c
index 8d5f2a4..1f84bb2 100644 (file)
@@ -42,6 +42,7 @@
 #include <modest-text-utils.h>
 #include <modest-icon-names.h>
 #include <modest-runtime.h>
+#include "modest-platform.h"
 
 static void modest_header_view_class_init  (ModestHeaderViewClass *klass);
 static void modest_header_view_init        (ModestHeaderView *obj);
@@ -67,15 +68,23 @@ static gboolean      on_focus_in            (GtkWidget     *sef,
                                             GdkEventFocus *event,
                                             gpointer       user_data);
 
+static void          folder_monitor_update  (TnyFolderObserver *self, 
+                                            TnyFolderChange *change);
+
+static void          tny_folder_observer_init (TnyFolderObserverIface *klass);
+
 typedef struct _ModestHeaderViewPrivate ModestHeaderViewPrivate;
 struct _ModestHeaderViewPrivate {
        TnyFolder            *folder;
        ModestHeaderViewStyle style;
 
        TnyFolderMonitor     *monitor;
-       GMutex               *monitor_lock;
-       gint sort_colid[2][TNY_FOLDER_TYPE_NUM];
-       gint sort_type[2][TNY_FOLDER_TYPE_NUM];
+       GMutex               *observers_lock;
+
+       gint                  sort_colid[2][TNY_FOLDER_TYPE_NUM];
+       gint                  sort_type[2][TNY_FOLDER_TYPE_NUM];
+
+
 };
 
 #define MODEST_HEADER_VIEW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
@@ -117,9 +126,21 @@ modest_header_view_get_type (void)
                        (GInstanceInitFunc) modest_header_view_init,
                        NULL
                };
+
+               static const GInterfaceInfo tny_folder_observer_info = 
+               {
+                       (GInterfaceInitFunc) tny_folder_observer_init, /* interface_init */
+                       NULL,         /* interface_finalize */
+                       NULL          /* interface_data */
+               };
                my_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
                                                  "ModestHeaderView",
                                                  &my_info, 0);
+
+               g_type_add_interface_static (my_type, TNY_TYPE_FOLDER_OBSERVER,
+                                            &tny_folder_observer_info);
+
+
        }
        return my_type;
 }
@@ -173,6 +194,12 @@ modest_header_view_class_init (ModestHeaderViewClass *klass)
                              G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
 }
 
+static void
+tny_folder_observer_init (TnyFolderObserverIface *klass)
+{
+       klass->update_func = folder_monitor_update;
+}
+
 static GtkTreeViewColumn*
 get_new_column (const gchar *name, GtkCellRenderer *renderer,
                gboolean resizable, gint sort_col_id, gboolean show_as_text,
@@ -209,7 +236,7 @@ static void
 remove_all_columns (ModestHeaderView *obj)
 {
        GList *columns, *cursor;
-
+       
        columns = gtk_tree_view_get_columns (GTK_TREE_VIEW(obj));
 
        for (cursor = columns; cursor; cursor = cursor->next)
@@ -385,6 +412,13 @@ modest_header_view_set_columns (ModestHeaderView *self, const GList *columns, Tn
                        g_return_val_if_reached(FALSE);
                }
 
+               if (sortable) {
+                       gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sortable),
+                                                        col,
+                                                        (GtkTreeIterCompareFunc) cmp_rows,
+                                                        column, NULL);
+               }
+
                /* we keep the column id around */
                g_object_set_data (G_OBJECT(column), MODEST_HEADER_VIEW_COLUMN,
                                   GINT_TO_POINTER(col));
@@ -393,9 +427,8 @@ modest_header_view_set_columns (ModestHeaderView *self, const GList *columns, Tn
                g_object_set_data (G_OBJECT(column), MODEST_HEADER_VIEW_PTR,
                                   self);
                gtk_tree_view_append_column (GTK_TREE_VIEW(self), column);              
-       }       
-       
-       
+       }               
+
        return TRUE;
 }
 
@@ -410,7 +443,7 @@ modest_header_view_init (ModestHeaderView *obj)
        priv->folder  = NULL;
 
        priv->monitor        = NULL;
-       priv->monitor_lock   = g_mutex_new ();
+       priv->observers_lock = g_mutex_new ();
 
        /* Sort parameters */
        for (j=0; j < 2; j++) {
@@ -432,19 +465,20 @@ modest_header_view_finalize (GObject *obj)
        self = MODEST_HEADER_VIEW(obj);
        priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
 
-       g_mutex_lock (priv->monitor_lock);
+       g_mutex_lock (priv->observers_lock);
        if (priv->monitor) {
                tny_folder_monitor_stop (priv->monitor);
                g_object_unref (G_OBJECT (priv->monitor));
        }
-       g_mutex_unlock (priv->monitor_lock);
-       g_mutex_free (priv->monitor_lock);
+       g_mutex_unlock (priv->observers_lock);
+       g_mutex_free (priv->observers_lock);
 
        if (priv->folder) {
+               tny_folder_remove_observer (priv->folder, TNY_FOLDER_OBSERVER (obj));
                g_object_unref (G_OBJECT (priv->folder));
                priv->folder   = NULL;
        }
-       
+
        G_OBJECT_CLASS(parent_class)->finalize (obj);
 }
 
@@ -699,68 +733,6 @@ modest_header_view_set_model (GtkTreeView *header_view, GtkTreeModel *model)
        return;
 }
 
-static void
-on_progress_changed (ModestMailOperation *mail_op,
-                    ModestHeaderView *self)
-{
-       TnyFolderType type;
-       GtkTreeModel *sortable; 
-       ModestHeaderViewPrivate *priv;
-       GList *cols, *cursor;
-       TnyList *headers;
-       guint sort_colid;
-       GtkSortType sort_type;
-
-       if (!modest_mail_operation_is_finished (mail_op))
-               return;
-
-       if (modest_mail_operation_get_error (mail_op))
-               return;
-       
-       priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
-
-       headers = TNY_LIST (tny_gtk_header_list_model_new ());
-
-       tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL(headers),
-                                             priv->folder, TRUE);
-
-       sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(headers));
-       g_object_unref (G_OBJECT (headers));
-       
-       /* install our special sorting functions */
-       cursor = cols = gtk_tree_view_get_columns (GTK_TREE_VIEW(self));
-       while (cursor) {
-               gint col_id = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(cursor->data),
-                                                                MODEST_HEADER_VIEW_COLUMN));
-               gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sortable),
-                                                col_id,
-                                                (GtkTreeIterCompareFunc) cmp_rows,
-                                                cursor->data, NULL);
-               cursor = g_list_next(cursor);
-       }
-       g_list_free (cols);
-
-       /* Restore sort column id */
-       type  = modest_tny_folder_guess_folder_type (priv->folder);
-       sort_colid = modest_header_view_get_sort_column_id (self, type); 
-       sort_type = modest_header_view_get_sort_type (self, type); 
-       gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sortable),
-                                             sort_colid,
-                                             sort_type);
-
-       /* Set new model */
-       modest_header_view_set_model (GTK_TREE_VIEW (self), sortable);
-       g_object_unref (G_OBJECT (sortable));
-
-       /* Add a folder observer */
-       g_mutex_lock (priv->monitor_lock);
-       priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (priv->folder));
-       tny_folder_monitor_add_list (priv->monitor, TNY_LIST (headers));
-       tny_folder_monitor_start (priv->monitor);
-       g_mutex_unlock (priv->monitor_lock);
-
-}
-
 TnyFolder*
 modest_header_view_get_folder (ModestHeaderView *self)
 {
@@ -791,8 +763,9 @@ modest_header_view_set_folder_intern (ModestHeaderView *self, TnyFolder *folder)
        tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL(headers),
                                              folder, FALSE);
 
-       /* Add a folder observer */
-       g_mutex_lock (priv->monitor_lock);
+       /* Add IDLE observer (monitor) and another folder observer for
+          new messages (self) */
+       g_mutex_lock (priv->observers_lock);
        if (priv->monitor) {
                tny_folder_monitor_stop (priv->monitor);
                g_object_unref (G_OBJECT (priv->monitor));
@@ -800,8 +773,8 @@ modest_header_view_set_folder_intern (ModestHeaderView *self, TnyFolder *folder)
        priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (folder));
        tny_folder_monitor_add_list (priv->monitor, TNY_LIST (headers));
        tny_folder_monitor_start (priv->monitor);
-       g_mutex_unlock (priv->monitor_lock);
-
+       tny_folder_add_observer (folder, TNY_FOLDER_OBSERVER (self));
+       g_mutex_unlock (priv->observers_lock);
 
        sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(headers));
        g_object_unref (G_OBJECT (headers));
@@ -817,19 +790,23 @@ modest_header_view_set_folder_intern (ModestHeaderView *self, TnyFolder *folder)
                                                 cursor->data, NULL);
                cursor = g_list_next(cursor);
        }
-       g_list_free (cols);
 
        /* Restore sort column id */
-       type  = modest_tny_folder_guess_folder_type (folder);
-       sort_colid = modest_header_view_get_sort_column_id (self, type); 
-       sort_type = modest_header_view_get_sort_type (self, type); 
-       gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sortable),
-                                             sort_colid,
-                                             sort_type);
+       if (cols) {
+               type  = modest_tny_folder_guess_folder_type (folder);
+               sort_colid = modest_header_view_get_sort_column_id (self, type); 
+               sort_type = modest_header_view_get_sort_type (self, type); 
+               gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sortable),
+                                                     sort_colid,
+                                                     sort_type);
+       }
 
        /* Set new model */
        modest_header_view_set_model (GTK_TREE_VIEW (self), sortable);
        g_object_unref (G_OBJECT (sortable));
+
+       /* Free */
+       g_list_free (cols);     
 }
 
 void
@@ -909,13 +886,17 @@ modest_header_view_set_folder (ModestHeaderView *self, TnyFolder *folder)
        priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
 
        if (priv->folder) {
+               g_mutex_lock (priv->observers_lock);
+               tny_folder_remove_observer (priv->folder, TNY_FOLDER_OBSERVER (self));
                g_object_unref (priv->folder);
                priv->folder = NULL;
+               g_mutex_unlock (priv->observers_lock);
        }
 
        if (folder) {
                ModestMailOperation *mail_op;
 
+               /* Set folder in the model */
                modest_header_view_set_folder_intern (self, folder);
 
                /* Pick my reference. Nothing to do with the mail operation */
@@ -925,14 +906,10 @@ modest_header_view_set_folder (ModestHeaderView *self, TnyFolder *folder)
                g_signal_emit (G_OBJECT(self), signals[HEADER_SELECTED_SIGNAL], 0, NULL);
 
                /* Create the mail operation */
-               mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE);
+               mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, NULL);
                modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
                                                 mail_op);
 
-               /* Register a mail operation observer */
-               g_signal_connect (mail_op, "progress-changed", 
-                                 G_CALLBACK (on_progress_changed), self);
-
                /* Refresh the folder asynchronously */
                modest_mail_operation_refresh_folder (mail_op, folder);
 
@@ -940,15 +917,16 @@ modest_header_view_set_folder (ModestHeaderView *self, TnyFolder *folder)
                g_object_unref (mail_op);
 
        } else {
-               g_mutex_lock (priv->monitor_lock);
-               modest_header_view_set_model (GTK_TREE_VIEW (self), NULL); 
+               g_mutex_lock (priv->observers_lock);
 
                if (priv->monitor) {
                        tny_folder_monitor_stop (priv->monitor);
                        g_object_unref (G_OBJECT (priv->monitor));
                        priv->monitor = NULL;
                }
-               g_mutex_unlock (priv->monitor_lock);
+               modest_header_view_set_model (GTK_TREE_VIEW (self), NULL); 
+
+               g_mutex_unlock (priv->observers_lock);
        }
 }
 
@@ -1050,7 +1028,7 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
        gint sort_colid;
        static int counter = 0;
 
-       g_return_val_if_fail (G_IS_OBJECT(user_data), 0);
+       g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN(user_data), 0);
        col_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(user_data), MODEST_HEADER_VIEW_COLUMN));
        
        if (!(++counter % 100)) {
@@ -1211,11 +1189,11 @@ drag_data_get_cb (GtkWidget *widget, GdkDragContext *context,
                  GtkSelectionData *selection_data, 
                  guint info,  guint time, gpointer data)
 {
-       GtkTreeModel *model;
+       GtkTreeModel *model = NULL;
        GtkTreeIter iter;
-       GtkTreePath *source_row;
+       GtkTreePath *source_row = NULL;
        
-       source_row = get_selected_row (GTK_TREE_VIEW(widget), &model);
+       source_row = get_selected_row (GTK_TREE_VIEW (widget), &model);
        if ((source_row == NULL) || (!gtk_tree_model_get_iter(model, &iter, source_row))) return;
 
        switch (info) {
@@ -1233,7 +1211,7 @@ drag_data_get_cb (GtkWidget *widget, GdkDragContext *context,
                break;
        }
        default:
-               g_message ("default");
+               g_message ("%s: default switch case.", __FUNCTION__);
        }
 
        gtk_tree_path_free (source_row);
@@ -1242,8 +1220,7 @@ drag_data_get_cb (GtkWidget *widget, GdkDragContext *context,
 /* Header view drag types */
 const GtkTargetEntry header_view_drag_types[] = {
        { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP, MODEST_HEADER_ROW },
-       { "text/uri-list",      0,                   MODEST_MSG },
+       { "text/uri-list",      0,                   MODEST_MSG }, 
 };
 
 static void
@@ -1348,3 +1325,38 @@ on_focus_in (GtkWidget     *self,
 
        return FALSE;
 }
+
+/*
+ *
+ */
+static void
+folder_monitor_update (TnyFolderObserver *self, 
+                      TnyFolderChange *change)
+{
+       ModestHeaderViewPrivate *priv = MODEST_HEADER_VIEW_GET_PRIVATE (self);
+       TnyFolderChangeChanged changed;
+
+       g_mutex_lock (priv->observers_lock);
+
+       changed = tny_folder_change_get_changed (change);
+
+       if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
+/*     TnyIterator *iter; */
+/*     TnyList *list; */
+/*             /\* The added headers *\/ */
+/*             list = tny_simple_list_new (); */
+/*             tny_folder_change_get_added_headers (change, list); */
+/*             iter = tny_list_create_iterator (list); */
+/*             while (!tny_iterator_is_done (iter)) */
+/*             { */
+/*                     TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter)); */
+/*                     g_object_unref (G_OBJECT (header)); */
+/*                     tny_iterator_next (iter); */
+/*             } */
+/*             g_object_unref (G_OBJECT (iter)); */
+/*             g_object_unref (G_OBJECT (list)); */
+               modest_platform_on_new_msg ();
+       }
+
+       g_mutex_unlock (priv->observers_lock);
+}