2 /* modest-tny-header-tree-view.c
4 #include <glib/gi18n.h>
5 #include "modest-tny-header-tree-view.h"
6 #include <tny-list-iface.h>
9 #include <modest-icon-names.h>
10 #include "modest-icon-factory.h"
12 /* 'private'/'protected' functions */
13 static void modest_tny_header_tree_view_class_init (ModestTnyHeaderTreeViewClass *klass);
14 static void modest_tny_header_tree_view_init (ModestTnyHeaderTreeView *obj);
15 static void modest_tny_header_tree_view_finalize (GObject *obj);
17 static void selection_changed (GtkTreeSelection *sel, gpointer user_data);
18 static void column_clicked (GtkTreeViewColumn *treeviewcolumn, gpointer user_data);
21 MESSAGE_SELECTED_SIGNAL,
25 typedef struct _ModestTnyHeaderTreeViewPrivate ModestTnyHeaderTreeViewPrivate;
26 struct _ModestTnyHeaderTreeViewPrivate {
28 TnyMsgFolderIface *tny_msg_folder;
29 TnyListIface *headers;
33 ModestTnyHeaderTreeViewStyle style;
35 #define MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
36 MODEST_TYPE_TNY_HEADER_TREE_VIEW, \
37 ModestTnyHeaderTreeViewPrivate))
39 static GObjectClass *parent_class = NULL;
41 /* uncomment the following if you have defined any signals */
42 static guint signals[LAST_SIGNAL] = {0};
45 modest_tny_header_tree_view_get_type (void)
47 static GType my_type = 0;
49 static const GTypeInfo my_info = {
50 sizeof(ModestTnyHeaderTreeViewClass),
52 NULL, /* base finalize */
53 (GClassInitFunc) modest_tny_header_tree_view_class_init,
54 NULL, /* class finalize */
55 NULL, /* class data */
56 sizeof(ModestTnyHeaderTreeView),
58 (GInstanceInitFunc) modest_tny_header_tree_view_init,
60 my_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
61 "ModestTnyHeaderTreeView",
68 modest_tny_header_tree_view_class_init (ModestTnyHeaderTreeViewClass *klass)
70 GObjectClass *gobject_class;
71 gobject_class = (GObjectClass*) klass;
73 parent_class = g_type_class_peek_parent (klass);
74 gobject_class->finalize = modest_tny_header_tree_view_finalize;
76 g_type_class_add_private (gobject_class, sizeof(ModestTnyHeaderTreeViewPrivate));
78 signals[MESSAGE_SELECTED_SIGNAL] =
79 g_signal_new ("message_selected",
80 G_TYPE_FROM_CLASS (gobject_class),
82 G_STRUCT_OFFSET (ModestTnyHeaderTreeViewClass,message_selected),
84 g_cclosure_marshal_VOID__POINTER,
85 G_TYPE_NONE, 1, G_TYPE_POINTER);
93 msgtype_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
94 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
96 TnyMsgHeaderFlags flags;
99 gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
102 if (flags & TNY_MSG_HEADER_FLAG_DELETED)
103 pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_DELETED);
104 else if (flags & TNY_MSG_HEADER_FLAG_SEEN)
105 pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_READ);
107 pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_UNREAD);
109 g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL);
113 attach_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
114 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
116 TnyMsgHeaderFlags flags;
117 GdkPixbuf *pixbuf = NULL;
119 gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
122 if (flags & TNY_MSG_HEADER_FLAG_ATTACHMENTS) {
123 pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_ATTACH);
125 g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL);
132 header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
133 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
135 TnyMsgHeaderFlags flags;
137 gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
140 g_object_set (G_OBJECT(renderer),
141 "weight", (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400: 800,
142 "style", (flags & TNY_MSG_HEADER_FLAG_DELETED) ?
143 PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL,
150 sender_receiver_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
151 GtkTreeModel *tree_model, GtkTreeIter *iter, gboolean is_sender)
153 TnyMsgHeaderFlags flags;
154 gchar *addr1, *addr2;
155 gint sender_receiver_col;
158 sender_receiver_col = TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN;
160 sender_receiver_col = TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN;
162 gtk_tree_model_get (tree_model, iter,
163 sender_receiver_col, &addr1,
164 TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
167 /* simplistic --> remove <email@address> from display */
168 addr2 = g_strstr_len (addr1, strlen(addr1), "<");
172 g_object_set (G_OBJECT(renderer),
174 "weight", (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400 : 800,
175 "style", (flags & TNY_MSG_HEADER_FLAG_DELETED) ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL,
182 /* not reentrant/thread-safe */
184 display_date (time_t date)
186 struct tm date_tm, now_tm;
189 const gint buf_size = 64;
190 static gchar date_buf[64]; /* buf_size is not ... */
191 static gchar now_buf[64]; /* ...const enough... */
195 localtime_r(&now, &now_tm);
196 localtime_r(&date, &date_tm);
198 /* get today's date */
199 strftime (date_buf, buf_size, "%x", &date_tm);
200 strftime (now_buf, buf_size, "%x", &now_tm); /* today */
202 /* if this is today, get the time instead of the date */
203 if (strcmp (date_buf, now_buf) == 0)
204 strftime (date_buf, buf_size, _("%X"), &date_tm);
211 compact_header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
212 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
215 TnyMsgHeaderFlags flags;
216 gchar *from, *subject;
221 gtk_tree_model_get (tree_model, iter,
222 TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
223 TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &from,
224 TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &subject,
225 TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, &date,
227 rendobj = G_OBJECT(renderer);
229 /* simplistic --> remove <email@address> from display */
230 address = g_strstr_len (from, strlen(from), "<");
232 address[0]='\0'; /* set a new endpoint */
234 header = g_strdup_printf ("%s %s\n%s", from,
235 display_date(date), subject);
236 g_object_set (G_OBJECT(renderer),
238 "weight", (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400: 800,
239 "style", (flags & TNY_MSG_HEADER_FLAG_DELETED) ?
240 PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL,
248 static GtkTreeViewColumn*
249 get_new_column (const gchar *name, GtkCellRenderer *renderer,
250 gboolean resizable, gint sort_col_id, gboolean show_as_text,
251 GtkTreeCellDataFunc cell_data_func, gpointer user_data)
253 GtkTreeViewColumn *column;
255 column = gtk_tree_view_column_new_with_attributes(name, renderer, NULL);
256 gtk_tree_view_column_set_resizable (column, resizable);
259 gtk_tree_view_column_add_attribute (column, renderer, "text",
261 if (sort_col_id >= 0)
262 gtk_tree_view_column_set_sort_column_id (column, sort_col_id);
264 gtk_tree_view_column_set_sort_indicator (column, FALSE);
265 gtk_tree_view_column_set_reorderable (column, TRUE);
268 gtk_tree_view_column_set_cell_data_func(column, renderer, cell_data_func,
271 /* g_signal_connect (G_OBJECT (column), "clicked", */
272 /* G_CALLBACK (column_clicked), obj); */
281 remove_all_columns (ModestTnyHeaderTreeView *obj)
283 GList *columns, *cursor;
285 columns = gtk_tree_view_get_columns (GTK_TREE_VIEW(obj));
287 for (cursor = columns; cursor; cursor = cursor->next)
288 gtk_tree_view_remove_column (GTK_TREE_VIEW(obj),
289 GTK_TREE_VIEW_COLUMN(cursor->data));
290 g_list_free (columns);
297 init_columns (ModestTnyHeaderTreeView *obj)
299 GtkTreeViewColumn *column;
300 GtkCellRenderer *renderer_msgtype,
304 ModestTnyHeaderTreeViewPrivate *priv;
307 priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(obj);
309 renderer_msgtype = gtk_cell_renderer_pixbuf_new ();
310 renderer_attach = gtk_cell_renderer_pixbuf_new ();
311 renderer_header = gtk_cell_renderer_text_new ();
313 remove_all_columns (obj);
315 for (cursor = priv->columns; cursor; cursor = cursor->next) {
316 ModestTnyHeaderTreeViewColumn col =
317 (ModestTnyHeaderTreeViewColumn) GPOINTER_TO_INT(cursor->data);
321 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE:
323 column = get_new_column (_("M"), renderer_msgtype, FALSE,
324 TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
325 FALSE, (GtkTreeCellDataFunc)msgtype_cell_data,
329 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH:
331 column = get_new_column (_("A"), renderer_attach, FALSE,
332 TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
333 FALSE, (GtkTreeCellDataFunc)attach_cell_data,
337 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE:
338 column = get_new_column (_("Received"), renderer_header, TRUE,
339 TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_COLUMN,
340 TRUE, (GtkTreeCellDataFunc)header_cell_data,
344 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM:
345 column = get_new_column (_("From"), renderer_header, TRUE,
346 TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN,
347 TRUE, (GtkTreeCellDataFunc)sender_receiver_cell_data,
348 GINT_TO_POINTER(TRUE));
351 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_TO:
352 column = get_new_column (_("To"), renderer_header, TRUE,
353 TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN,
354 TRUE, (GtkTreeCellDataFunc)sender_receiver_cell_data,
355 GINT_TO_POINTER(FALSE));
358 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_COMPACT_HEADER:
359 column = get_new_column (_("Header"), renderer_header, TRUE,
360 TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN,
361 TRUE, (GtkTreeCellDataFunc)compact_header_cell_data,
365 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT:
366 column = get_new_column (_("Subject"), renderer_header, TRUE,
367 TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN,
368 TRUE, (GtkTreeCellDataFunc)header_cell_data,
373 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SENT_DATE:
374 column = get_new_column (_("Sent"), renderer_header, TRUE,
375 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_COLUMN,
376 TRUE, (GtkTreeCellDataFunc)header_cell_data,
380 gtk_tree_view_append_column (GTK_TREE_VIEW(obj), column);
389 modest_tny_header_tree_view_init (ModestTnyHeaderTreeView *obj)
395 modest_tny_header_tree_view_finalize (GObject *obj)
397 ModestTnyHeaderTreeView *self;
398 ModestTnyHeaderTreeViewPrivate *priv;
400 self = MODEST_TNY_HEADER_TREE_VIEW(obj);
401 priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
404 g_object_unref (G_OBJECT(priv->headers));
406 priv->headers = NULL;
407 priv->tny_msg_folder = NULL;
411 modest_tny_header_tree_view_new (TnyMsgFolderIface *folder,
413 ModestTnyHeaderTreeViewStyle style)
416 GtkTreeSelection *sel;
417 ModestTnyHeaderTreeView *self;
419 obj = G_OBJECT(g_object_new(MODEST_TYPE_TNY_HEADER_TREE_VIEW, NULL));
420 self = MODEST_TNY_HEADER_TREE_VIEW(obj);
422 if (!modest_tny_header_tree_view_set_folder (self, NULL)) {
423 g_warning ("could not set the folder");
424 g_object_unref (obj);
428 modest_tny_header_tree_view_set_style (self, style);
429 modest_tny_header_tree_view_set_columns (self, columns);
432 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(obj), TRUE);
433 gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(obj), TRUE);
435 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(obj),
436 TRUE); /* alternating row colors */
438 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
439 g_signal_connect (sel, "changed",
440 G_CALLBACK(selection_changed), self);
442 return GTK_WIDGET(self);
446 modest_tny_header_tree_view_set_columns (ModestTnyHeaderTreeView *self, GSList *columns)
448 ModestTnyHeaderTreeViewPrivate *priv;
451 g_return_val_if_fail (self, FALSE);
453 priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
455 g_slist_free (priv->columns);
457 for (cursor = columns; cursor; cursor = cursor->next) {
458 ModestTnyHeaderTreeViewColumn col =
459 (ModestTnyHeaderTreeViewColumn) GPOINTER_TO_INT(cursor->data);
460 if (0 > col || col >= MODEST_TNY_HEADER_TREE_VIEW_COLUMN_NUM)
461 g_warning ("invalid column in column list");
463 priv->columns = g_slist_append (priv->columns, cursor->data);
466 init_columns (self); /* redraw them */
473 modest_tny_header_tree_view_get_columns (ModestTnyHeaderTreeView *self)
475 ModestTnyHeaderTreeViewPrivate *priv;
477 g_return_val_if_fail (self, FALSE);
479 priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
480 return priv->columns;
487 modest_tny_header_tree_view_set_style (ModestTnyHeaderTreeView *self,
488 ModestTnyHeaderTreeViewStyle style)
490 g_return_val_if_fail (self, FALSE);
491 g_return_val_if_fail (style >= 0 && style < MODEST_TNY_HEADER_TREE_VIEW_STYLE_NUM,
494 MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self)->style = style;
499 ModestTnyHeaderTreeViewStyle
500 modest_tny_header_tree_view_get_style (ModestTnyHeaderTreeView *self)
502 g_return_val_if_fail (self, FALSE);
504 return MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self)->style;
509 /* get the length of any prefix that should be ignored for sorting */
511 get_prefix_len (const gchar *sub)
514 const static gchar* prefix[] = {"Re:", "RE:", "Fwd:", "FWD:", "FW:", NULL};
516 if (sub[0] != 'R' && sub[0] != 'F') /* optimization */
520 if (g_str_has_prefix(sub, prefix[i])) {
521 int prefix_len = strlen(prefix[i]);
522 if (sub[prefix_len] == ' ')
523 ++prefix_len; /* ignore space after prefix as well */
533 cmp_normalized_subject (const gchar* s1, const gchar *s2)
536 return strcmp (s1 + get_prefix_len(s1),
537 s2 + get_prefix_len(s2));
542 cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
545 gint col_id = GPOINTER_TO_INT (user_data);
551 g_return_val_if_fail (GTK_IS_TREE_MODEL(tree_model), -1);
555 /* first one, we decide based on the time */
556 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_COMPACT_HEADER:
557 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE:
558 gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN,
560 gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN,
564 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SENT_DATE:
565 gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
567 gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
572 /* next ones, we try the search criteria first, if they're the same, then we use 'sent date' */
573 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT: {
575 gtk_tree_model_get (tree_model, iter1,
576 TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s1,
577 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
579 gtk_tree_model_get (tree_model, iter2,
580 TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s2,
581 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
584 cmp = cmp_normalized_subject(s1, s2);
589 return cmp ? cmp : t1 - t2;
592 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM:
594 gtk_tree_model_get (tree_model, iter1,
595 TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s1,
596 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
598 gtk_tree_model_get (tree_model, iter2,
599 TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s2,
600 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
602 cmp = strcmp (s1, s2);
606 return cmp ? cmp : t1 - t2;
608 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_TO:
610 gtk_tree_model_get (tree_model, iter1,
611 TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s1,
612 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
614 gtk_tree_model_get (tree_model, iter2,
615 TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s2,
616 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
618 cmp = strcmp (s1, s2);
622 return cmp ? cmp : t1 - t2;
624 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH:
626 gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1,
627 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, -1);
628 gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2,
629 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, -1);
631 cmp = (val1 & TNY_MSG_HEADER_FLAG_ATTACHMENTS) - (val2 & TNY_MSG_HEADER_FLAG_ATTACHMENTS);
633 return cmp ? cmp : t1 - t2;
635 case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE:
636 gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1,
637 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,-1);
638 gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2,
639 TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,-1);
640 cmp = (val1 & TNY_MSG_HEADER_FLAG_SEEN) - (val2 & TNY_MSG_HEADER_FLAG_SEEN);
642 return cmp ? cmp : t1 - t2;
645 return &iter1 - &iter2; /* oughhhh */
652 modest_tny_header_tree_view_set_folder (ModestTnyHeaderTreeView *self,
653 TnyMsgFolderIface *folder)
655 GtkTreeModel *oldsortable, *sortable;
656 ModestTnyHeaderTreeViewPrivate *priv;
658 g_return_val_if_fail (self, FALSE);
660 priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
665 priv->headers = TNY_LIST_IFACE(tny_msg_header_list_model_new ());
666 tny_msg_folder_iface_get_headers (folder, priv->headers,
668 tny_msg_header_list_model_set_folder (TNY_MSG_HEADER_LIST_MODEL(priv->headers),
671 oldsortable = gtk_tree_view_get_model(GTK_TREE_VIEW (self));
672 if (oldsortable && GTK_IS_TREE_MODEL_SORT(oldsortable)) {
673 GtkTreeModel *oldmodel = gtk_tree_model_sort_get_model
674 (GTK_TREE_MODEL_SORT(oldsortable));
676 g_object_unref (G_OBJECT(oldmodel));
677 g_object_unref (oldsortable);
680 sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(priv->headers));
682 /* install our special sorting functions */
685 int col_id = GPOINTER_TO_INT (col->data);
686 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sortable), col_id,
687 (GtkTreeIterCompareFunc)cmp_rows,
688 GINT_TO_POINTER(col_id), NULL);
692 gtk_tree_view_set_model (GTK_TREE_VIEW (self), sortable);
693 gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(self), TRUE);
694 /* no need to unref sortable */
696 } else /* when there is no folder */
697 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(self), FALSE);
704 selection_changed (GtkTreeSelection *sel, gpointer user_data)
707 TnyMsgHeaderIface *header;
709 ModestTnyHeaderTreeView *tree_view;
711 g_return_if_fail (sel);
712 g_return_if_fail (user_data);
714 if (!gtk_tree_selection_get_selected (sel, &model, &iter))
715 return; /* msg was _un_selected */
717 tree_view = MODEST_TNY_HEADER_TREE_VIEW (user_data);
719 gtk_tree_model_get (model, &iter,
720 TNY_MSG_HEADER_LIST_MODEL_INSTANCE_COLUMN,
724 const TnyMsgIface *msg;
725 const TnyMsgFolderIface *folder;
727 folder = tny_msg_header_iface_get_folder (TNY_MSG_HEADER_IFACE(header));
729 g_message ("cannot find folder");
731 msg = tny_msg_folder_iface_get_message (TNY_MSG_FOLDER_IFACE(folder),
734 g_message ("cannot find msg");
735 gtk_tree_store_remove (GTK_TREE_STORE(model),
740 g_signal_emit (G_OBJECT(tree_view), signals[MESSAGE_SELECTED_SIGNAL], 0,
743 /* mark message as seen; _set_flags crashes, bug in tinymail? */
744 //flags = tny_msg_header_iface_get_flags (TNY_MSG_HEADER_IFACE(header));
745 //tny_msg_header_iface_set_flags (header, TNY_MSG_HEADER_FLAG_SEEN);
750 column_clicked (GtkTreeViewColumn *col, gpointer user_data)
752 GtkTreeView *treeview;
755 treeview = GTK_TREE_VIEW (user_data);
756 id = gtk_tree_view_column_get_sort_column_id (col);
758 gtk_tree_view_set_search_column (treeview, id);