+ return MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self)->style;
+}
+
+
+
+/* get the length of any prefix that should be ignored for sorting */
+static inline int
+get_prefix_len (const gchar *sub)
+{
+ gint i = 0;
+ const static gchar* prefix[] = {"Re:", "RE:", "Fwd:", "FWD:", "FW:", "AW:", NULL};
+
+ if (sub[0] != 'R' && sub[0] != 'F') /* optimization */
+ return 0;
+
+ while (prefix[i]) {
+ if (g_str_has_prefix(sub, prefix[i])) {
+ int prefix_len = strlen(prefix[i]);
+ if (sub[prefix_len] == ' ')
+ ++prefix_len; /* ignore space after prefix as well */
+ return prefix_len;
+ }
+ ++i;
+ }
+ return 0;
+}
+
+
+static inline gint
+cmp_normalized_subject (const gchar* s1, const gchar *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;
+}
+
+
+static gint
+cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
+ gpointer user_data)
+{
+ gint col_id = GPOINTER_TO_INT (user_data);
+ gint t1, t2;
+ gint val1, val2;
+ gchar *s1, *s2;
+ gint cmp;
+
+ g_return_val_if_fail (GTK_IS_TREE_MODEL(tree_model), -1);
+
+ switch (col_id) {
+
+ /* first one, we decide based on the time */
+ case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_COMPACT_HEADER:
+ case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE:
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN,
+ &t1,-1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN,
+ &t2,-1);
+ return t1 - t2;
+
+ case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SENT_DATE:
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
+ &t1,-1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
+ &t2,-1);
+ return t1 - t2;
+
+
+ /* next ones, we try the search criteria first, if they're the same, then we use 'sent date' */
+ case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT: {
+
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
+ -1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
+ -1);
+
+ cmp = cmp_normalized_subject(s1, s2);
+
+ g_free (s1);
+ g_free (s2);
+
+ return cmp ? cmp : t1 - t2;
+ }
+
+ case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM:
+
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
+ -1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
+ -1);
+ cmp = strcmp (s1, s2);
+ g_free (s1);
+ g_free (s2);
+
+ return cmp ? cmp : t1 - t2;
+
+ case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_TO:
+
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
+ -1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
+ -1);
+ cmp = strcmp (s1, s2);
+ g_free (s1);
+ g_free (s2);
+
+ return cmp ? cmp : t1 - t2;
+
+ case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH:
+
+ gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, -1);
+ gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, -1);
+
+ cmp = (val1 & TNY_MSG_HEADER_FLAG_ATTACHMENTS) -
+ (val2 & TNY_MSG_HEADER_FLAG_ATTACHMENTS);
+
+ return cmp ? cmp : t1 - t2;
+
+ case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE:
+ gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,-1);
+ gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,-1);
+ cmp = (val1 & TNY_MSG_HEADER_FLAG_SEEN) - (val2 & TNY_MSG_HEADER_FLAG_SEEN);
+
+ return cmp ? cmp : t1 - t2;
+
+ default:
+ return &iter1 - &iter2; /* oughhhh */
+ }
+}
+
+
+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_if_fail (self);
+
+ if (cancelled)
+ return;
+