X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fmodest-tny-header-tree-view.c;h=eb9b0ef579b90bab73120613b3c22c9f3514b1b8;hb=7302009c7bd53f51df0cb8e6521a73d0b8e729aa;hp=d7c56c47db1a5574e57543483e8bbe9cc5c6fe09;hpb=3165ffeeee3bfa260c86ad5ecee3f29bf686a798;p=modest diff --git a/src/modest-tny-header-tree-view.c b/src/modest-tny-header-tree-view.c index d7c56c4..eb9b0ef 100644 --- a/src/modest-tny-header-tree-view.c +++ b/src/modest-tny-header-tree-view.c @@ -5,6 +5,7 @@ #include "modest-tny-header-tree-view.h" #include #include +#include "modest-marshal.h" #include #include "modest-icon-factory.h" @@ -16,9 +17,11 @@ static void modest_tny_header_tree_view_finalize (GObject *obj); static void selection_changed (GtkTreeSelection *sel, gpointer user_data); static void column_clicked (GtkTreeViewColumn *treeviewcolumn, gpointer user_data); +static gboolean refresh_folder_finish_status_update (gpointer user_data); enum { MESSAGE_SELECTED_SIGNAL, + STATUS_UPDATE_SIGNAL, LAST_SIGNAL }; @@ -28,7 +31,8 @@ struct _ModestTnyHeaderTreeViewPrivate { TnyMsgFolderIface *tny_msg_folder; TnyListIface *headers; - GSList *columns; + gint status_id; + GSList *columns; ModestTnyHeaderTreeViewStyle style; }; @@ -82,7 +86,16 @@ modest_tny_header_tree_view_class_init (ModestTnyHeaderTreeViewClass *klass) G_STRUCT_OFFSET (ModestTnyHeaderTreeViewClass,message_selected), NULL, NULL, g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); + G_TYPE_NONE, 1, G_TYPE_POINTER); + + signals[STATUS_UPDATE_SIGNAL] = + g_signal_new ("status_update", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestTnyHeaderTreeViewClass,message_selected), + NULL, NULL, + modest_marshal_VOID__STRING_INT, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT); } @@ -94,7 +107,7 @@ msgtype_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data) { TnyMsgHeaderFlags flags; - GdkPixbuf *pixbuf; + GdkPixbuf *pixbuf = NULL; gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, -1); @@ -105,8 +118,8 @@ msgtype_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_READ); else pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_UNREAD); - if (pixbuf) - g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL); + + g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL); } static void @@ -119,13 +132,11 @@ attach_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, -1); - if (flags & TNY_MSG_HEADER_FLAG_ATTACHMENTS) { + if (flags & TNY_MSG_HEADER_FLAG_ATTACHMENTS) pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_ATTACH); - if (pixbuf) - g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL); - } -} + g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL); +} static void @@ -296,7 +307,7 @@ remove_all_columns (ModestTnyHeaderTreeView *obj) static void init_columns (ModestTnyHeaderTreeView *obj) { - GtkTreeViewColumn *column; + GtkTreeViewColumn *column=NULL; GtkCellRenderer *renderer_msgtype, *renderer_header, *renderer_attach; @@ -388,7 +399,10 @@ init_columns (ModestTnyHeaderTreeView *obj) static void modest_tny_header_tree_view_init (ModestTnyHeaderTreeView *obj) { - + ModestTnyHeaderTreeViewPrivate *priv; + priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(obj); + + priv->status_id = 0; } static void @@ -438,7 +452,7 @@ modest_tny_header_tree_view_new (TnyMsgFolderIface *folder, sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self)); g_signal_connect (sel, "changed", G_CALLBACK(selection_changed), self); - + return GTK_WIDGET(self); } @@ -507,11 +521,11 @@ modest_tny_header_tree_view_get_style (ModestTnyHeaderTreeView *self) /* get the length of any prefix that should be ignored for sorting */ -static int +static inline int get_prefix_len (const gchar *sub) { - int i = 0; - const static gchar* prefix[] = {"Re:", "RE:", "Fwd:", "FWD:", "FW:", NULL}; + gint i = 0; + const static gchar* prefix[] = {"Re:", "RE:", "Fwd:", "FWD:", "FW:", "AW:", NULL}; if (sub[0] != 'R' && sub[0] != 'F') /* optimization */ return 0; @@ -529,12 +543,20 @@ get_prefix_len (const gchar *sub) } -static gint +static inline gint cmp_normalized_subject (const gchar* s1, const gchar *s2) { - /* FIXME: utf8 */ - return strcmp (s1 + get_prefix_len(s1), - s2 + get_prefix_len(s2)); + gint result = 0; + register gchar *n1, *n2; + + n1 = g_utf8_collate_key (s1 + get_prefix_len(s1), -1); + n2 = g_utf8_collate_key (s2 + get_prefix_len(s2), -1); + + result = strcmp (n1, n2); + g_free (n1); + g_free (n2); + + return result; } @@ -647,26 +669,33 @@ cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2, } - -gboolean -modest_tny_header_tree_view_set_folder (ModestTnyHeaderTreeView *self, - TnyMsgFolderIface *folder) +static void +refresh_folder (TnyMsgFolderIface *folder, gboolean cancelled, + gpointer user_data) { GtkTreeModel *oldsortable, *sortable; + ModestTnyHeaderTreeView *self = + MODEST_TNY_HEADER_TREE_VIEW(user_data); ModestTnyHeaderTreeViewPrivate *priv; - - g_return_val_if_fail (self, FALSE); + g_return_if_fail (self); + + if (cancelled) + return; + priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self); + + if (!folder) /* when there is no folder */ + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(self), FALSE); - if (folder) { + else { /* it's a new one or a refresh */ GSList *col; - + priv->headers = TNY_LIST_IFACE(tny_msg_header_list_model_new ()); - tny_msg_folder_iface_get_headers (folder, priv->headers, - FALSE); + + tny_msg_folder_iface_get_headers (folder, priv->headers, FALSE); tny_msg_header_list_model_set_folder (TNY_MSG_HEADER_LIST_MODEL(priv->headers), - folder, TRUE); + folder, TRUE); /* async */ oldsortable = gtk_tree_view_get_model(GTK_TREE_VIEW (self)); if (oldsortable && GTK_IS_TREE_MODEL_SORT(oldsortable)) { @@ -682,7 +711,7 @@ modest_tny_header_tree_view_set_folder (ModestTnyHeaderTreeView *self, /* install our special sorting functions */ col = priv->columns; while (col) { - int col_id = GPOINTER_TO_INT (col->data); + gint col_id = GPOINTER_TO_INT (col->data); gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sortable), col_id, (GtkTreeIterCompareFunc)cmp_rows, GINT_TO_POINTER(col_id), NULL); @@ -692,14 +721,82 @@ modest_tny_header_tree_view_set_folder (ModestTnyHeaderTreeView *self, gtk_tree_view_set_model (GTK_TREE_VIEW (self), sortable); gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(self), TRUE); /* no need to unref sortable */ - - } else /* when there is no folder */ + } +} + + +static void +refresh_folder_status_update (TnyMsgFolderIface *folder, const gchar *msg, + gint status_id, gpointer user_data) +{ + ModestTnyHeaderTreeView *self; + ModestTnyHeaderTreeViewPrivate *priv; + + self = MODEST_TNY_HEADER_TREE_VIEW (user_data); + priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self); + + g_signal_emit (G_OBJECT(self), + signals[STATUS_UPDATE_SIGNAL], 0, + msg, status_id); + if (msg) + g_timeout_add (750, + (GSourceFunc)refresh_folder_finish_status_update, + self); + + priv->status_id = status_id; +} + + +static gboolean +refresh_folder_finish_status_update (gpointer user_data) +{ + ModestTnyHeaderTreeView *self; + ModestTnyHeaderTreeViewPrivate *priv; + + self = MODEST_TNY_HEADER_TREE_VIEW (user_data); + priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self); + + if (priv->status_id == 0) + return FALSE; + + refresh_folder_status_update (NULL, NULL, priv->status_id, + user_data); + priv->status_id = 0; + + return FALSE; +} + + +gboolean +modest_tny_header_tree_view_set_folder (ModestTnyHeaderTreeView *self, + TnyMsgFolderIface *folder) +{ + ModestTnyHeaderTreeViewPrivate *priv; + + + g_return_val_if_fail (MODEST_IS_TNY_HEADER_TREE_VIEW (self), FALSE); + + priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self); + + if (!folder) {/* when there is no folder */ + GtkTreeModel *model; + model = gtk_tree_view_get_model (GTK_TREE_VIEW(self)); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(self), FALSE); - + gtk_tree_view_set_model (GTK_TREE_VIEW (self), NULL); + if (model) + g_object_unref (model); + } + else { /* it's a new one or a refresh */ + tny_msg_folder_iface_refresh_async (folder, + refresh_folder, + refresh_folder_status_update, + self); + } return TRUE; } + static void selection_changed (GtkTreeSelection *sel, gpointer user_data) { @@ -721,7 +818,7 @@ selection_changed (GtkTreeSelection *sel, gpointer user_data) &header, -1); if (header) { - const TnyMsgIface *msg; + const TnyMsgIface *msg = NULL; const TnyMsgFolderIface *folder; folder = tny_msg_header_iface_get_folder (TNY_MSG_HEADER_IFACE(header));