[evolution] ETableSortInfo: Rework API to avoid exposing ETableSortColumn.



commit ad5ed0d603b0b915865bef3c4edc996378696187
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Jun 28 10:11:21 2013 -0400

    ETableSortInfo: Rework API to avoid exposing ETableSortColumn.
    
    Replace ETableSortColumn with separate ETableColumnSpecification and
    GtkSortType parameters in the "get_nth" and "set_nth" functions.
    
    Makes some other parts of the code simpler since it no longer has to
    translate a column number to a column specification.

 .../evolution-util/evolution-util-sections.txt     |    1 -
 e-util/e-table-config.c                            |  180 +++++++-------
 e-util/e-table-group-container.c                   |    9 +-
 e-util/e-table-header-item.c                       |  264 +++++++++++---------
 e-util/e-table-sort-info.c                         |  268 ++++++++++++++------
 e-util/e-table-sort-info.h                         |   84 ++++---
 e-util/e-table-sorter.c                            |   30 ++-
 e-util/e-table-sorting-utils.c                     |   51 ++--
 e-util/e-table-utils.c                             |   36 ++--
 mail/message-list.c                                |   22 +-
 10 files changed, 549 insertions(+), 396 deletions(-)
---
diff --git a/doc/reference/evolution-util/evolution-util-sections.txt 
b/doc/reference/evolution-util/evolution-util-sections.txt
index c303f74..a5d2330 100644
--- a/doc/reference/evolution-util/evolution-util-sections.txt
+++ b/doc/reference/evolution-util/evolution-util-sections.txt
@@ -3874,7 +3874,6 @@ e_table_sort_info_get_can_group
 e_table_sort_info_set_can_group
 e_table_sort_info_grouping_get_count
 e_table_sort_info_grouping_truncate
-ETableSortColumn
 e_table_sort_info_grouping_get_nth
 e_table_sort_info_grouping_set_nth
 e_table_sort_info_sorting_get_count
diff --git a/e-util/e-table-config.c b/e-util/e-table-config.c
index cf0c4e6..8f339b5 100644
--- a/e-util/e-table-config.c
+++ b/e-util/e-table-config.c
@@ -238,10 +238,10 @@ configure_combo_box_set_active (GtkComboBox *combo_box,
 }
 
 static ETableColumnSpecification *
-find_column_in_spec (ETableSpecification *spec,
-                     gint model_col)
+find_column_spec_by_name (ETableSpecification *spec,
+                          const gchar *s)
 {
-       ETableColumnSpecification *column = NULL;
+       ETableColumnSpecification *column;
        GPtrArray *array;
        guint ii;
 
@@ -255,7 +255,7 @@ find_column_in_spec (ETableSpecification *spec,
                if (candidate->disabled)
                        continue;
 
-               if (candidate->model_col == model_col) {
+               if (g_ascii_strcasecmp (candidate->title, s) == 0) {
                        column = candidate;
                        break;
                }
@@ -266,35 +266,6 @@ find_column_in_spec (ETableSpecification *spec,
        return column;
 }
 
-static gint
-find_model_column_by_name (ETableSpecification *spec,
-                           const gchar *s)
-{
-       GPtrArray *array;
-       gint model_col = -1;
-       guint ii;
-
-       array = e_table_specification_ref_columns (spec);
-
-       for (ii = 0; ii < array->len; ii++) {
-               ETableColumnSpecification *candidate;
-
-               candidate = g_ptr_array_index (array, ii);
-
-               if (candidate->disabled)
-                       continue;
-
-               if (g_ascii_strcasecmp (candidate->title, s) == 0) {
-                       model_col = candidate->model_col;
-                       break;
-               }
-       }
-
-       g_ptr_array_unref (array);
-
-       return model_col;
-}
-
 static void
 update_sort_and_group_config_dialog (ETableConfig *config,
                                      gboolean is_sort)
@@ -329,20 +300,20 @@ update_sort_and_group_config_dialog (ETableConfig *config,
                        widgets[i].changed_id);
 
                if (i < count) {
-                       GtkToggleButton *a, *d;
-                       ETableSortColumn col =
-                               is_sort
-                               ? e_table_sort_info_sorting_get_nth (
-                                       config->temp_state->sort_info,
-                                       i)
-                               :  e_table_sort_info_grouping_get_nth (
-                                       config->temp_state->sort_info,
-                                       i);
-
-                       ETableColumnSpecification *column =
-                               find_column_in_spec (config->source_spec, col.column);
-
-                       if (!column) {
+                       GtkWidget *toggle_button;
+                       ETableColumnSpecification *column;
+                       GtkSortType sort_type;
+
+                       if (is_sort)
+                               column = e_table_sort_info_sorting_get_nth (
+                                       config->temp_state->sort_info, i,
+                                       &sort_type);
+                       else
+                               column = e_table_sort_info_grouping_get_nth (
+                                       config->temp_state->sort_info, i,
+                                       &sort_type);
+
+                       if (column == NULL) {
                                /*
                                 * This is a bug in the programmer
                                 * stuff, but by the time we arrive
@@ -357,12 +328,15 @@ update_sort_and_group_config_dialog (ETableConfig *config,
                        /*
                         * Update radio buttons
                         */
-                       a = GTK_TOGGLE_BUTTON (
-                               widgets[i].radio_ascending);
-                       d = GTK_TOGGLE_BUTTON (
-                               widgets[i].radio_descending);
 
-                       gtk_toggle_button_set_active (col.ascending ? a : d, 1);
+                       if (sort_type == GTK_SORT_ASCENDING)
+                               toggle_button = widgets[i].radio_ascending;
+                       else
+                               toggle_button = widgets[i].radio_descending;
+
+                       gtk_toggle_button_set_active (
+                               GTK_TOGGLE_BUTTON (toggle_button), TRUE);
+
                } else {
                        GtkToggleButton *t;
 
@@ -396,19 +370,23 @@ update_sort_and_group_config_dialog (ETableConfig *config,
 static void
 config_sort_info_update (ETableConfig *config)
 {
-       ETableSortInfo *info = config->state->sort_info;
+       ETableSortInfo *sort_info;
        GString *res;
        gint count, i;
 
-       count = e_table_sort_info_sorting_get_count (info);
+       sort_info = config->state->sort_info;
+
+       count = e_table_sort_info_sorting_get_count (sort_info);
        res = g_string_new ("");
 
        for (i = 0; i < count; i++) {
-               ETableSortColumn col = e_table_sort_info_sorting_get_nth (info, i);
                ETableColumnSpecification *column;
+               GtkSortType sort_type;
+
+               column = e_table_sort_info_sorting_get_nth (
+                       sort_info, i, &sort_type);
 
-               column = find_column_in_spec (config->source_spec, col.column);
-               if (!column) {
+               if (column == NULL) {
                        g_warning ("Could not find column model in specification");
                        continue;
                }
@@ -417,7 +395,7 @@ config_sort_info_update (ETableConfig *config)
                g_string_append_c (res, ' ');
                g_string_append (
                        res,
-                       col.ascending ?
+                       (sort_type == GTK_SORT_ASCENDING) ?
                        _("(Ascending)") : _("(Descending)"));
 
                if ((i + 1) != count)
@@ -435,22 +413,26 @@ config_sort_info_update (ETableConfig *config)
 static void
 config_group_info_update (ETableConfig *config)
 {
-       ETableSortInfo *info = config->state->sort_info;
+       ETableSortInfo *sort_info;
        GString *res;
        gint count, i;
 
-       if (!e_table_sort_info_get_can_group (info))
+       sort_info = config->state->sort_info;
+
+       if (!e_table_sort_info_get_can_group (sort_info))
                return;
 
-       count = e_table_sort_info_grouping_get_count (info);
+       count = e_table_sort_info_grouping_get_count (sort_info);
        res = g_string_new ("");
 
        for (i = 0; i < count; i++) {
-               ETableSortColumn col = e_table_sort_info_grouping_get_nth (info, i);
                ETableColumnSpecification *column;
+               GtkSortType sort_type;
+
+               column = e_table_sort_info_grouping_get_nth (
+                       sort_info, i, &sort_type);
 
-               column = find_column_in_spec (config->source_spec, col.column);
-               if (!column) {
+               if (column == NULL) {
                        g_warning ("Could not find model column in specification");
                        continue;
                }
@@ -459,7 +441,7 @@ config_group_info_update (ETableConfig *config)
                g_string_append_c (res, ' ');
                g_string_append (
                        res,
-                       col.ascending ?
+                       (sort_type == GTK_SORT_ASCENDING) ?
                        _("(Ascending)") : _("(Descending)"));
 
                if ((i + 1) != count)
@@ -850,18 +832,18 @@ sort_combo_changed (GtkComboBox *combo_box,
        ETableConfig *config = sort->e_table_config;
        ETableSortInfo *sort_info = config->temp_state->sort_info;
        ETableConfigSortWidgets *base = &config->sort[0];
-       GtkToggleButton *toggle_button;
        gint idx = sort - base;
        gchar *s;
 
        s = configure_combo_box_get_active (combo_box);
 
        if (s != NULL) {
-               ETableSortColumn c;
-               gint col;
+               ETableColumnSpecification *column;
+               GtkToggleButton *toggle_button;
+               GtkSortType sort_type;
 
-               col = find_model_column_by_name (config->source_spec, s);
-               if (col == -1) {
+               column = find_column_spec_by_name (config->source_spec, s);
+               if (column == NULL) {
                        g_warning ("sort: This should not happen (%s)", s);
                        g_free (s);
                        return;
@@ -869,9 +851,13 @@ sort_combo_changed (GtkComboBox *combo_box,
 
                toggle_button = GTK_TOGGLE_BUTTON (
                        config->sort[idx].radio_ascending);
-               c.ascending = gtk_toggle_button_get_active (toggle_button);
-               c.column = col;
-               e_table_sort_info_sorting_set_nth (sort_info, idx, c);
+               if (gtk_toggle_button_get_active (toggle_button))
+                       sort_type = GTK_SORT_ASCENDING;
+               else
+                       sort_type = GTK_SORT_DESCENDING;
+
+               e_table_sort_info_sorting_set_nth (
+                       sort_info, idx, column, sort_type);
 
                update_sort_and_group_config_dialog (config, TRUE);
        }  else {
@@ -883,18 +869,23 @@ sort_combo_changed (GtkComboBox *combo_box,
 }
 
 static void
-sort_ascending_toggled (GtkToggleButton *t,
+sort_ascending_toggled (GtkToggleButton *toggle_button,
                         ETableConfigSortWidgets *sort)
 {
        ETableConfig *config = sort->e_table_config;
        ETableSortInfo *si = config->temp_state->sort_info;
        ETableConfigSortWidgets *base = &config->sort[0];
+       ETableColumnSpecification *column;
+       GtkSortType sort_type;
        gint idx = sort - base;
-       ETableSortColumn c;
 
-       c = e_table_sort_info_sorting_get_nth (si, idx);
-       c.ascending = gtk_toggle_button_get_active (t);
-       e_table_sort_info_sorting_set_nth (si, idx, c);
+       if (gtk_toggle_button_get_active (toggle_button))
+               sort_type = GTK_SORT_ASCENDING;
+       else
+               sort_type = GTK_SORT_DESCENDING;
+
+       column = e_table_sort_info_sorting_get_nth (si, idx, NULL);
+       e_table_sort_info_sorting_set_nth (si, idx, column, sort_type);
 }
 
 static void
@@ -982,12 +973,12 @@ group_combo_changed (GtkComboBox *combo_box,
        s = configure_combo_box_get_active (combo_box);
 
        if (s != NULL) {
+               ETableColumnSpecification *column;
                GtkToggleButton *toggle_button;
-               ETableSortColumn c;
-               gint col;
+               GtkSortType sort_type;
 
-               col = find_model_column_by_name (config->source_spec, s);
-               if (col == -1) {
+               column = find_column_spec_by_name (config->source_spec, s);
+               if (column == NULL) {
                        g_warning ("grouping: this should not happen, %s", s);
                        g_free (s);
                        return;
@@ -995,9 +986,13 @@ group_combo_changed (GtkComboBox *combo_box,
 
                toggle_button = GTK_TOGGLE_BUTTON (
                        config->group[idx].radio_ascending);
-               c.ascending = gtk_toggle_button_get_active (toggle_button);
-               c.column = col;
-               e_table_sort_info_grouping_set_nth (sort_info, idx, c);
+               if (gtk_toggle_button_get_active (toggle_button))
+                       sort_type = GTK_SORT_ASCENDING;
+               else
+                       sort_type = GTK_SORT_DESCENDING;
+
+               e_table_sort_info_grouping_set_nth (
+                       sort_info, idx, column, sort_type);
 
                update_sort_and_group_config_dialog (config, FALSE);
        }  else {
@@ -1009,18 +1004,23 @@ group_combo_changed (GtkComboBox *combo_box,
 }
 
 static void
-group_ascending_toggled (GtkToggleButton *t,
+group_ascending_toggled (GtkToggleButton *toggle_button,
                          ETableConfigSortWidgets *group)
 {
        ETableConfig *config = group->e_table_config;
        ETableSortInfo *si = config->temp_state->sort_info;
        ETableConfigSortWidgets *base = &config->group[0];
+       ETableColumnSpecification *column;
+       GtkSortType sort_type;
        gint idx = group - base;
-       ETableSortColumn c;
 
-       c = e_table_sort_info_grouping_get_nth (si, idx);
-       c.ascending = gtk_toggle_button_get_active (t);
-       e_table_sort_info_grouping_set_nth (si, idx, c);
+       if (gtk_toggle_button_get_active (toggle_button))
+               sort_type = GTK_SORT_ASCENDING;
+       else
+               sort_type = GTK_SORT_DESCENDING;
+
+       column = e_table_sort_info_grouping_get_nth (si, idx, NULL);
+       e_table_sort_info_grouping_set_nth (si, idx, column, sort_type);
 }
 
 static void
diff --git a/e-util/e-table-group-container.c b/e-util/e-table-group-container.c
index 68239b1..d828dde 100644
--- a/e-util/e-table-group-container.c
+++ b/e-util/e-table-group-container.c
@@ -150,12 +150,15 @@ e_table_group_container_construct (GnomeCanvasGroup *parent,
                                    ETableSortInfo *sort_info,
                                    gint n)
 {
+       ETableColumnSpecification *spec;
        ETableCol *col;
-       ETableSortColumn column = e_table_sort_info_grouping_get_nth (sort_info, n);
        GtkWidget *widget;
        GtkStyle *style;
+       GtkSortType sort_type;
+
+       spec = e_table_sort_info_grouping_get_nth (sort_info, n, &sort_type);
+       col = e_table_header_get_column_by_spec (full_header, spec);
 
-       col = e_table_header_get_column_by_col_idx (full_header, column.column);
        if (col == NULL) {
                gint last = e_table_header_count (full_header) - 1;
                col = e_table_header_get_column (full_header, last);
@@ -166,7 +169,7 @@ e_table_group_container_construct (GnomeCanvasGroup *parent,
        etgc->ecol = g_object_ref (col);
        etgc->sort_info = g_object_ref (sort_info);
        etgc->n = n;
-       etgc->ascending = column.ascending;
+       etgc->ascending = (sort_type == GTK_SORT_ASCENDING);
 
        widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etgc)->canvas);
        style = gtk_widget_get_style (widget);
diff --git a/e-util/e-table-header-item.c b/e-util/e-table-header-item.c
index 8dcdf06..ea7145c 100644
--- a/e-util/e-table-header-item.c
+++ b/e-util/e-table-header-item.c
@@ -997,32 +997,34 @@ ethi_draw (GnomeCanvasItem *item,
 
                length = e_table_sort_info_grouping_get_count (ethi->sort_info);
                for (i = 0; i < length; i++) {
-                       ETableSortColumn column;
+                       ETableColumnSpecification *spec;
+                       GtkSortType sort_type;
 
-                       column = e_table_sort_info_grouping_get_nth (
-                               ethi->sort_info, i);
+                       spec = e_table_sort_info_grouping_get_nth (
+                               ethi->sort_info, i, &sort_type);
 
                        g_hash_table_insert (
                                arrows,
-                               GINT_TO_POINTER ((gint) column.column),
+                               GINT_TO_POINTER (spec->model_col),
                                GINT_TO_POINTER (
-                                       column.ascending ?
+                                       (sort_type == GTK_SORT_ASCENDING) ?
                                        E_TABLE_COL_ARROW_DOWN :
                                        E_TABLE_COL_ARROW_UP));
                }
 
                length = e_table_sort_info_sorting_get_count (ethi->sort_info);
                for (i = 0; i < length; i++) {
-                       ETableSortColumn column;
+                       ETableColumnSpecification *spec;
+                       GtkSortType sort_type;
 
-                       column = e_table_sort_info_sorting_get_nth (
-                               ethi->sort_info, i);
+                       spec = e_table_sort_info_sorting_get_nth (
+                               ethi->sort_info, i, &sort_type);
 
                        g_hash_table_insert (
                                arrows,
-                               GINT_TO_POINTER ((gint) column.column),
+                               GINT_TO_POINTER (spec->model_col),
                                GINT_TO_POINTER (
-                                       column.ascending ?
+                                       (sort_type == GTK_SORT_ASCENDING) ?
                                        E_TABLE_COL_ARROW_DOWN :
                                        E_TABLE_COL_ARROW_UP));
                }
@@ -1241,29 +1243,35 @@ ethi_start_drag (ETableHeaderItem *ethi,
                gint length = e_table_sort_info_grouping_get_count (ethi->sort_info);
                gint i;
                for (i = 0; i < length; i++) {
-                       ETableSortColumn column =
-                               e_table_sort_info_grouping_get_nth (
-                                       ethi->sort_info, i);
+                       ETableColumnSpecification *spec;
+                       GtkSortType sort_type;
+
                        group_indent++;
+
+                       spec = e_table_sort_info_grouping_get_nth (
+                               ethi->sort_info, i, &sort_type);
+
                        g_hash_table_insert (
                                arrows,
-                               GINT_TO_POINTER ((gint) column.column),
+                               GINT_TO_POINTER (spec->model_col),
                                GINT_TO_POINTER (
-                                       column.ascending ?
+                                       (sort_type == GTK_SORT_ASCENDING) ?
                                        E_TABLE_COL_ARROW_DOWN :
                                        E_TABLE_COL_ARROW_UP));
                }
                length = e_table_sort_info_sorting_get_count (ethi->sort_info);
                for (i = 0; i < length; i++) {
-                       ETableSortColumn column =
-                               e_table_sort_info_sorting_get_nth (
-                                       ethi->sort_info, i);
+                       ETableColumnSpecification *spec;
+                       GtkSortType sort_type;
+
+                       spec = e_table_sort_info_sorting_get_nth (
+                               ethi->sort_info, i, &sort_type);
 
                        g_hash_table_insert (
                                arrows,
-                               GINT_TO_POINTER ((gint) column.column),
+                               GINT_TO_POINTER (spec->model_col),
                                GINT_TO_POINTER (
-                                       column.ascending ?
+                                       (sort_type == GTK_SORT_ASCENDING) ?
                                        E_TABLE_COL_ARROW_DOWN :
                                        E_TABLE_COL_ARROW_UP));
                }
@@ -1304,8 +1312,8 @@ static void
 ethi_popup_sort_ascending (GtkWidget *widget,
                            EthiHeaderInfo *info)
 {
+       ETableColumnSpecification *col_spec = NULL;
        ETableCol *col;
-       gint model_col = -1;
        gint length;
        gint i;
        gint found = FALSE;
@@ -1313,46 +1321,49 @@ ethi_popup_sort_ascending (GtkWidget *widget,
 
        col = e_table_header_get_column (ethi->eth, info->col);
        if (col->spec->sortable)
-               model_col = col->spec->model_col;
+               col_spec = col->spec;
 
        length = e_table_sort_info_grouping_get_count (ethi->sort_info);
        for (i = 0; i < length; i++) {
-               ETableSortColumn column = e_table_sort_info_grouping_get_nth (
-                       ethi->sort_info, i);
+               ETableColumnSpecification *spec;
+
+               spec = e_table_sort_info_grouping_get_nth (
+                       ethi->sort_info, i, NULL);
 
-               if (model_col == column.column) {
-                       column.ascending = 1;
+               if (e_table_column_specification_equal (col_spec, spec)) {
                        e_table_sort_info_grouping_set_nth (
-                               ethi->sort_info, i, column);
-                       found = 1;
-                       break;
+                               ethi->sort_info, i, spec,
+                               GTK_SORT_ASCENDING);
+                       return;
                }
        }
-       if (!found) {
-               length = e_table_sort_info_sorting_get_count (
-                       ethi->sort_info);
-               for (i = 0; i < length; i++) {
-                       ETableSortColumn column =
-                               e_table_sort_info_sorting_get_nth (
-                                       ethi->sort_info, i);
-                       if (model_col == column.column || model_col == -1) {
-                               column.ascending = 1;
-                               e_table_sort_info_sorting_set_nth (
-                                       ethi->sort_info, i, column);
-                               found = 1;
-                               if (model_col != -1)
-                                       break;
-                       }
+
+       length = e_table_sort_info_sorting_get_count (ethi->sort_info);
+       for (i = 0; i < length; i++) {
+               ETableColumnSpecification *spec;
+
+               spec = e_table_sort_info_sorting_get_nth (
+                       ethi->sort_info, i, NULL);
+
+               if (col_spec == NULL ||
+                   e_table_column_specification_equal (col_spec, spec)) {
+                       e_table_sort_info_sorting_set_nth (
+                               ethi->sort_info, i, spec,
+                               GTK_SORT_ASCENDING);
+                       found = TRUE;
+                       if (col_spec != NULL)
+                               return;
                }
        }
+
        if (!found) {
-               ETableSortColumn column;
-               column.column = model_col;
-               column.ascending =  1;
                length = e_table_sort_info_sorting_get_count (ethi->sort_info);
                if (length == 0)
                        length++;
-               e_table_sort_info_sorting_set_nth (ethi->sort_info, length - 1, column);
+
+               e_table_sort_info_sorting_set_nth (
+                       ethi->sort_info, length - 1,
+                       col_spec, GTK_SORT_ASCENDING);
        }
 }
 
@@ -1360,8 +1371,8 @@ static void
 ethi_popup_sort_descending (GtkWidget *widget,
                             EthiHeaderInfo *info)
 {
+       ETableColumnSpecification *col_spec = NULL;
        ETableCol *col;
-       gint model_col=-1;
        gint length;
        gint i;
        gint found = FALSE;
@@ -1369,46 +1380,50 @@ ethi_popup_sort_descending (GtkWidget *widget,
 
        col = e_table_header_get_column (ethi->eth, info->col);
        if (col->spec->sortable)
-               model_col = col->spec->model_col;
+               col_spec = col->spec;
 
        length = e_table_sort_info_grouping_get_count (ethi->sort_info);
        for (i = 0; i < length; i++) {
-               ETableSortColumn column = e_table_sort_info_grouping_get_nth (
-                       ethi->sort_info, i);
-               if (model_col == column.column) {
-                       column.ascending = 0;
+               ETableColumnSpecification *spec;
+               GtkSortType sort_type;
+
+               spec = e_table_sort_info_grouping_get_nth (
+                       ethi->sort_info, i, &sort_type);
+
+               if (e_table_column_specification_equal (col_spec, spec)) {
                        e_table_sort_info_grouping_set_nth (
-                               ethi->sort_info, i, column);
-                       found = 1;
-                       break;
+                               ethi->sort_info, i, spec,
+                               GTK_SORT_DESCENDING);
+                       return;
                }
        }
-       if (!found) {
-               length = e_table_sort_info_sorting_get_count (ethi->sort_info);
-               for (i = 0; i < length; i++) {
-                       ETableSortColumn column =
-                               e_table_sort_info_sorting_get_nth (
-                                       ethi->sort_info, i);
-
-                       if (model_col == column.column || model_col == -1) {
-                               column.ascending = 0;
-                               e_table_sort_info_sorting_set_nth (
-                                       ethi->sort_info, i, column);
-                               found = 1;
-                               if (model_col != -1)
-                                       break;
-                       }
+
+       length = e_table_sort_info_sorting_get_count (ethi->sort_info);
+       for (i = 0; i < length; i++) {
+               ETableColumnSpecification *spec;
+
+               spec = e_table_sort_info_sorting_get_nth (
+                       ethi->sort_info, i, NULL);
+
+               if (col_spec == NULL ||
+                   e_table_column_specification_equal (col_spec, spec)) {
+                       e_table_sort_info_sorting_set_nth (
+                               ethi->sort_info, i, spec,
+                               GTK_SORT_DESCENDING);
+                       found = TRUE;
+                       if (col_spec != NULL)
+                               break;
                }
        }
+
        if (!found) {
-               ETableSortColumn column;
-               column.column = model_col;
-               column.ascending = 0;
                length = e_table_sort_info_sorting_get_count (ethi->sort_info);
                if (length == 0)
                        length++;
+
                e_table_sort_info_sorting_set_nth (
-                       ethi->sort_info, length - 1, column);
+                       ethi->sort_info, length - 1,
+                       col_spec, GTK_SORT_DESCENDING);
        }
 }
 
@@ -1427,17 +1442,13 @@ ethi_popup_group_field (GtkWidget *widget,
                         EthiHeaderInfo *info)
 {
        ETableCol *col;
-       gint model_col;
-       ETableHeaderItem *ethi = info->ethi;
-       ETableSortColumn column;
 
-       col = e_table_header_get_column (ethi->eth, info->col);
-       model_col = col->spec->model_col;
+       col = e_table_header_get_column (info->ethi->eth, info->col);
 
-       column.column = model_col;
-       column.ascending = 1;
-       e_table_sort_info_grouping_set_nth (ethi->sort_info, 0, column);
-       e_table_sort_info_grouping_truncate (ethi->sort_info, 1);
+       e_table_sort_info_grouping_set_nth (
+               info->ethi->sort_info, 0,
+               col->spec, GTK_SORT_ASCENDING);
+       e_table_sort_info_grouping_truncate (info->ethi->sort_info, 1);
 }
 
 static void
@@ -1632,10 +1643,11 @@ sort_by_id (GtkWidget *menu_item,
 
        if (!clearfirst && ecol &&
                e_table_sort_info_sorting_get_count (ethi->sort_info) == 1) {
-               ETableSortColumn column;
+               ETableColumnSpecification *spec;
 
-               column = e_table_sort_info_sorting_get_nth (ethi->sort_info, 0);
-               clearfirst = ecol->spec->sortable && ecol->spec->model_col != column.column;
+               spec = e_table_sort_info_sorting_get_nth (
+                       ethi->sort_info, 0, NULL);
+               clearfirst = ecol->spec->sortable && ecol->spec != spec;
        }
 
        if (clearfirst)
@@ -1659,7 +1671,6 @@ ethi_header_context_menu (ETableHeaderItem *ethi,
        GtkMenu *popup;
        gint ncol, sort_count, sort_col;
        GtkWidget *menu_item, *sub_menu;
-       ETableSortColumn column;
        gboolean ascending = TRUE;
        gdouble event_x_win = 0;
        gdouble event_y_win = 0;
@@ -1695,9 +1706,14 @@ ethi_header_context_menu (ETableHeaderItem *ethi,
        if (sort_count > 1 || sort_count < 1)
                sort_col = -1; /* Custom sorting */
        else {
-               column = e_table_sort_info_sorting_get_nth (ethi->sort_info, 0);
-               sort_col = column.column;
-               ascending = column.ascending;
+               ETableColumnSpecification *spec;
+               GtkSortType sort_type;
+
+               spec = e_table_sort_info_sorting_get_nth (
+                       ethi->sort_info, 0, &sort_type);
+
+               sort_col = spec->model_col;
+               ascending = (sort_type == GTK_SORT_ASCENDING);
        }
 
        /* Custom */
@@ -1773,7 +1789,7 @@ void
 ethi_change_sort_state (ETableHeaderItem *ethi,
                         ETableCol *col)
 {
-       gint model_col = -1;
+       ETableColumnSpecification *col_spec = NULL;
        gint length;
        gint i;
        gboolean found = FALSE;
@@ -1782,22 +1798,28 @@ ethi_change_sort_state (ETableHeaderItem *ethi,
                return;
 
        if (col->spec->sortable)
-               model_col = col->spec->model_col;
+               col_spec = col->spec;
 
        length = e_table_sort_info_grouping_get_count (ethi->sort_info);
        for (i = 0; i < length; i++) {
-               ETableSortColumn column;
+               ETableColumnSpecification *spec;
+               GtkSortType sort_type;
+
+               spec = e_table_sort_info_grouping_get_nth (
+                       ethi->sort_info, i, &sort_type);
 
-               column = e_table_sort_info_grouping_get_nth (
-                       ethi->sort_info, i);
+               /* Invert the sort type. */
+               if (sort_type == GTK_SORT_ASCENDING)
+                       sort_type = GTK_SORT_DESCENDING;
+               else
+                       sort_type = GTK_SORT_ASCENDING;
 
-               if (model_col == column.column || model_col == -1) {
-                       gint ascending = column.ascending;
-                       ascending = !ascending;
-                       column.ascending = ascending;
-                       e_table_sort_info_grouping_set_nth (ethi->sort_info, i, column);
+               if (col_spec == NULL ||
+                   e_table_column_specification_equal (col_spec, spec)) {
+                       e_table_sort_info_grouping_set_nth (
+                               ethi->sort_info, i, spec, sort_type);
                        found = TRUE;
-                       if (model_col != -1)
+                       if (col_spec != NULL)
                                break;
                }
        }
@@ -1805,15 +1827,15 @@ ethi_change_sort_state (ETableHeaderItem *ethi,
        if (!found) {
                length = e_table_sort_info_sorting_get_count (ethi->sort_info);
                for (i = 0; i < length; i++) {
-                       ETableSortColumn column;
-
-                       column = e_table_sort_info_sorting_get_nth (
-                               ethi->sort_info, i);
+                       ETableColumnSpecification *spec;
+                       GtkSortType sort_type;
 
-                       if (model_col == column.column || model_col == -1) {
-                               gint ascending = column.ascending;
+                       spec = e_table_sort_info_sorting_get_nth (
+                               ethi->sort_info, i, &sort_type);
 
-                               if (ascending == 0 && model_col != -1) {
+                       if (col_spec == NULL ||
+                           e_table_column_specification_equal (col_spec, spec)) {
+                               if (sort_type == GTK_SORT_DESCENDING && col_spec != NULL) {
                                        /*
                                         * This means the user has clicked twice
                                         * already, lets kill sorting of this column now.
@@ -1823,24 +1845,28 @@ ethi_change_sort_state (ETableHeaderItem *ethi,
                                        length--;
                                        i--;
                                } else {
-                                       ascending = !ascending;
-                                       column.ascending = ascending;
+                                       /* Invert the sort type. */
+                                       if (sort_type == GTK_SORT_ASCENDING)
+                                               sort_type = GTK_SORT_DESCENDING;
+                                       else
+                                               sort_type = GTK_SORT_ASCENDING;
+
                                        e_table_sort_info_sorting_set_nth (
-                                               ethi->sort_info, i, column);
+                                               ethi->sort_info, i, spec, sort_type);
                                }
                                found = TRUE;
-                               if (model_col != -1)
+                               if (col_spec != NULL)
                                        break;
                        }
                }
        }
 
-       if (!found && model_col != -1) {
-               ETableSortColumn column;
-               column.column = model_col;
-               column.ascending = 1;
+       if (!found && col_spec != NULL) {
                e_table_sort_info_sorting_truncate (ethi->sort_info, 0);
-               e_table_sort_info_sorting_set_nth (ethi->sort_info, 0, column);
+
+               e_table_sort_info_sorting_set_nth (
+                       ethi->sort_info, 0,
+                       col_spec, GTK_SORT_ASCENDING);
        }
 }
 
diff --git a/e-util/e-table-sort-info.c b/e-util/e-table-sort-info.c
index 047e31d..28e96f7 100644
--- a/e-util/e-table-sort-info.c
+++ b/e-util/e-table-sort-info.c
@@ -27,6 +27,8 @@
        (G_TYPE_INSTANCE_GET_PRIVATE \
        ((obj), E_TYPE_TABLE_SORT_INFO, ETableSortInfoPrivate))
 
+typedef struct _ColumnData ColumnData;
+
 struct _ETableSortInfoPrivate {
        GWeakRef specification;
        GArray *groupings;
@@ -34,6 +36,11 @@ struct _ETableSortInfoPrivate {
        gboolean can_group;
 };
 
+struct _ColumnData {
+       ETableColumnSpecification *column_spec;
+       GtkSortType sort_type;
+};
+
 enum {
        PROP_0,
        PROP_SPECIFICATION
@@ -50,6 +57,12 @@ static guint signals[LAST_SIGNAL];
 G_DEFINE_TYPE (ETableSortInfo , e_table_sort_info, G_TYPE_OBJECT)
 
 static void
+column_data_clear (ColumnData *data)
+{
+       g_clear_object (&data->column_spec);
+}
+
+static void
 table_sort_info_set_specification (ETableSortInfo *sort_info,
                                    ETableSpecification *specification)
 {
@@ -173,9 +186,16 @@ e_table_sort_info_init (ETableSortInfo *sort_info)
        sort_info->priv = E_TABLE_SORT_INFO_GET_PRIVATE (sort_info);
 
        sort_info->priv->groupings = g_array_new (
-               FALSE, TRUE, sizeof (ETableSortColumn));
+               FALSE, TRUE, sizeof (ColumnData));
+       g_array_set_clear_func (
+               sort_info->priv->groupings,
+               (GDestroyNotify) column_data_clear);
+
        sort_info->priv->sortings = g_array_new (
-               FALSE, TRUE, sizeof (ETableSortColumn));
+               FALSE, TRUE, sizeof (ColumnData));
+       g_array_set_clear_func (
+               sort_info->priv->sortings,
+               (GDestroyNotify) column_data_clear);
 
        sort_info->priv->can_group = TRUE;
 }
@@ -279,53 +299,67 @@ e_table_sort_info_grouping_truncate (ETableSortInfo *sort_info,
  * e_table_sort_info_grouping_get_nth:
  * @sort_info: an #ETableSortInfo
  * @n: Item information to fetch.
+ * @out_sort_type: return location for a #GtkSortType value, or %NULL
  *
  * Returns: the description of the @n-th grouping criteria in the @info object.
  */
-ETableSortColumn
+ETableColumnSpecification *
 e_table_sort_info_grouping_get_nth (ETableSortInfo *sort_info,
-                                    guint n)
+                                    guint n,
+                                    GtkSortType *out_sort_type)
 {
-       ETableSortColumn column = { 0, 0 };
+       ETableColumnSpecification *column_spec = NULL;
        GArray *array;
+       gboolean can_group;
 
-       g_return_val_if_fail (E_IS_TABLE_SORT_INFO (sort_info), column);
+       g_return_val_if_fail (E_IS_TABLE_SORT_INFO (sort_info), NULL);
 
        array = sort_info->priv->groupings;
+       can_group = e_table_sort_info_get_can_group (sort_info);
+
+       if (can_group && n < array->len) {
+               ColumnData *column_data;
 
-       if (!e_table_sort_info_get_can_group (sort_info))
-               return column;
+               column_data = &g_array_index (array, ColumnData, n);
 
-       if (n < array->len)
-               column = g_array_index (array, ETableSortColumn, n);
+               if (out_sort_type != NULL)
+                       *out_sort_type = column_data->sort_type;
 
-       return column;
+               column_spec = column_data->column_spec;
+       }
+
+       return column_spec;
 }
 
 /**
  * e_table_sort_info_grouping_set_nth:
  * @sort_info: an #ETableSortInfo
  * @n: Item information to fetch.
- * @column: new values for the grouping
+ * @spec: an #ETableColumnSpecification
+ * @sort_type: a #GtkSortType
  *
- * Sets the grouping criteria for index @n to be given by @column
- * (a column number and whether it is ascending or descending).
+ * Sets the grouping criteria for index @n to @spec and @sort_type.
  */
 void
 e_table_sort_info_grouping_set_nth (ETableSortInfo *sort_info,
                                     guint n,
-                                    ETableSortColumn column)
+                                    ETableColumnSpecification *spec,
+                                    GtkSortType sort_type)
 {
-       ETableSortColumn *array_element;
        GArray *array;
+       ColumnData *column_data;
 
        g_return_if_fail (E_IS_TABLE_SORT_INFO (sort_info));
+       g_return_if_fail (E_IS_TABLE_COLUMN_SPECIFICATION (spec));
 
        array = sort_info->priv->groupings;
        g_array_set_size (array, MAX (n + 1, array->len));
+       column_data = &g_array_index (array, ColumnData, n);
+
+       column_data_clear (column_data);
 
-       array_element = &g_array_index (array, ETableSortColumn, n);
-       *array_element = column;
+       column_data->column_spec = g_object_ref (spec);
+       column_data->sort_type = sort_type;
 
        g_signal_emit (sort_info, signals[GROUP_INFO_CHANGED], 0);
 }
@@ -386,50 +420,65 @@ e_table_sort_info_sorting_truncate (ETableSortInfo *sort_info,
  * e_table_sort_info_sorting_get_nth:
  * @sort_info: an #ETableSortInfo
  * @n: Item information to fetch.
+ * @out_sort_type: return location for a #GtkSortType value, or %NULL
  *
  * Returns: the description of the @n-th grouping criteria in the @info object.
  */
-ETableSortColumn
+ETableColumnSpecification *
 e_table_sort_info_sorting_get_nth (ETableSortInfo *sort_info,
-                                   guint n)
+                                   guint n,
+                                   GtkSortType *out_sort_type)
 {
-       ETableSortColumn column = { 0, 0 };
+       ETableColumnSpecification *column_spec = NULL;
        GArray *array;
 
-       g_return_val_if_fail (E_IS_TABLE_SORT_INFO (sort_info), column);
+       g_return_val_if_fail (E_IS_TABLE_SORT_INFO (sort_info), NULL);
 
        array = sort_info->priv->sortings;
 
-       if (n < array->len)
-               column = g_array_index (array, ETableSortColumn, n);
+       if (n < array->len) {
+               ColumnData *column_data;
+
+               column_data = &g_array_index (array, ColumnData, n);
 
-       return column;
+               if (out_sort_type != NULL)
+                       *out_sort_type = column_data->sort_type;
+
+               column_spec = column_data->column_spec;
+       }
+
+       return column_spec;
 }
 
 /**
  * e_table_sort_info_sorting_set_nth:
  * @sort_info: an #ETableSortInfo
  * @n: Item information to fetch.
- * @column: new values for the sorting
+ * @spec: an #ETableColumnSpecification
+ * @sort_type: a #GtkSortType
  *
- * Sets the sorting criteria for index @n to be given by @column (a
- * column number and whether it is ascending or descending).
+ * Sets the sorting criteria for index @n to @spec and @sort_type.
  */
 void
 e_table_sort_info_sorting_set_nth (ETableSortInfo *sort_info,
                                    guint n,
-                                   ETableSortColumn column)
+                                   ETableColumnSpecification *spec,
+                                   GtkSortType sort_type)
 {
-       ETableSortColumn *array_element;
        GArray *array;
+       ColumnData *column_data;
 
        g_return_if_fail (E_IS_TABLE_SORT_INFO (sort_info));
+       g_return_if_fail (E_IS_TABLE_COLUMN_SPECIFICATION (spec));
 
        array = sort_info->priv->sortings;
        g_array_set_size (array, MAX (n + 1, array->len));
+       column_data = &g_array_index (array, ColumnData, n);
 
-       array_element = &g_array_index (array, ETableSortColumn, n);
-       *array_element = column;
+       column_data_clear (column_data);
+
+       column_data->column_spec = g_object_ref (spec);
+       column_data->sort_type = sort_type;
 
        g_signal_emit (sort_info, signals[SORT_INFO_CHANGED], 0);
 }
@@ -448,47 +497,71 @@ e_table_sort_info_load_from_node (ETableSortInfo *sort_info,
                                   xmlNode *node,
                                   gdouble state_version)
 {
-       guint i;
+       ETableSpecification *specification;
+       GPtrArray *columns;
        xmlNode *grouping;
+       guint gcnt = 0;
+       guint scnt = 0;
 
        g_return_if_fail (E_IS_TABLE_SORT_INFO (sort_info));
        g_return_if_fail (node != NULL);
 
-       if (state_version <= 0.05) {
-               i = 0;
-               for (grouping = node->xmlChildrenNode; grouping && !strcmp ((gchar *) grouping->name, 
"group"); grouping = grouping->xmlChildrenNode) {
-                       ETableSortColumn column;
-                       column.column = e_xml_get_integer_prop_by_name (grouping, (const guchar *)"column");
-                       column.ascending = e_xml_get_bool_prop_by_name (grouping, (const guchar 
*)"ascending");
-                       e_table_sort_info_grouping_set_nth (sort_info, i++, column);
-               }
-               i = 0;
-               for (; grouping && !strcmp ((gchar *) grouping->name, "leaf"); grouping = 
grouping->xmlChildrenNode) {
-                       ETableSortColumn column;
-                       column.column = e_xml_get_integer_prop_by_name (grouping, (const guchar *)"column");
-                       column.ascending = e_xml_get_bool_prop_by_name (grouping, (const guchar 
*)"ascending");
-                       e_table_sort_info_sorting_set_nth (sort_info, i++, column);
+       specification = e_table_sort_info_ref_specification (sort_info);
+       columns = e_table_specification_ref_columns (specification);
+
+       for (grouping = node->children; grouping; grouping = grouping->next) {
+
+               if (grouping->type != XML_ELEMENT_NODE)
+                       continue;
+
+               if (g_str_equal ((gchar *) grouping->name, "group")) {
+                       GtkSortType sort_type;
+                       gboolean ascending;
+                       guint index;
+
+                       index = e_xml_get_integer_prop_by_name (
+                               grouping, (guchar *) "column");
+                       ascending = e_xml_get_bool_prop_by_name (
+                               grouping, (guchar *) "ascending");
+
+                       if (ascending)
+                               sort_type = GTK_SORT_ASCENDING;
+                       else
+                               sort_type = GTK_SORT_DESCENDING;
+
+                       if (index < columns->len)
+                               e_table_sort_info_grouping_set_nth (
+                                       sort_info, gcnt++,
+                                       columns->pdata[index],
+                                       sort_type);
                }
-       } else {
-               guint gcnt = 0;
-               guint scnt = 0;
-               for (grouping = node->children; grouping; grouping = grouping->next) {
-                       ETableSortColumn column;
-
-                       if (grouping->type != XML_ELEMENT_NODE)
-                               continue;
-
-                       if (!strcmp ((gchar *) grouping->name, "group")) {
-                               column.column = e_xml_get_integer_prop_by_name (grouping, (const guchar 
*)"column");
-                               column.ascending = e_xml_get_bool_prop_by_name (grouping, (const guchar 
*)"ascending");
-                               e_table_sort_info_grouping_set_nth (sort_info, gcnt++, column);
-                       } else if (!strcmp ((gchar *) grouping->name, "leaf")) {
-                               column.column = e_xml_get_integer_prop_by_name (grouping, (const guchar 
*)"column");
-                               column.ascending = e_xml_get_bool_prop_by_name (grouping, (const guchar 
*)"ascending");
-                               e_table_sort_info_sorting_set_nth (sort_info, scnt++, column);
-                       }
+
+               if (g_str_equal ((gchar *) grouping->name, "leaf")) {
+                       GtkSortType sort_type;
+                       gboolean ascending;
+                       gint index;;
+
+                       index = e_xml_get_integer_prop_by_name (
+                               grouping, (guchar *) "column");
+                       ascending = e_xml_get_bool_prop_by_name (
+                               grouping, (guchar *) "ascending");
+
+                       if (ascending)
+                               sort_type = GTK_SORT_ASCENDING;
+                       else
+                               sort_type = GTK_SORT_DESCENDING;
+
+                       if (index < columns->len)
+                               e_table_sort_info_sorting_set_nth (
+                                       sort_info, scnt++,
+                                       columns->pdata[index],
+                               sort_type);
                }
        }
+
+       g_object_unref (specification);
+       g_ptr_array_unref (columns);
+
        g_signal_emit (sort_info, signals[SORT_INFO_CHANGED], 0);
 }
 
@@ -506,40 +579,77 @@ xmlNode *
 e_table_sort_info_save_to_node (ETableSortInfo *sort_info,
                                 xmlNode *parent)
 {
+       ETableSpecification *specification;
        xmlNode *grouping;
        guint sort_count;
        guint group_count;
-       guint i;
+       guint ii;
 
        g_return_val_if_fail (E_IS_TABLE_SORT_INFO (sort_info), NULL);
 
        sort_count = e_table_sort_info_sorting_get_count (sort_info);
        group_count = e_table_sort_info_grouping_get_count (sort_info);
 
-       grouping = xmlNewChild (parent, NULL, (const guchar *)"grouping", NULL);
+       grouping = xmlNewChild (parent, NULL, (guchar *) "grouping", NULL);
 
-       for (i = 0; i < group_count; i++) {
-               ETableSortColumn column;
+       specification = e_table_sort_info_ref_specification (sort_info);
+
+       for (ii = 0; ii < group_count; ii++) {
+               ETableColumnSpecification *column_spec;
+               GtkSortType sort_type;
                xmlNode *new_node;
+               gint index;
+
+               column_spec = e_table_sort_info_grouping_get_nth (
+                       sort_info, ii, &sort_type);
+
+               index = e_table_specification_get_column_index (
+                       specification, column_spec);
+
+               if (index < 0) {
+                       g_warn_if_reached ();
+                       continue;
+               }
 
-               column = e_table_sort_info_grouping_get_nth (sort_info, i);
-               new_node = xmlNewChild (grouping, NULL, (const guchar *)"group", NULL);
+               new_node = xmlNewChild (
+                       grouping, NULL, (guchar *) "group", NULL);
 
-               e_xml_set_integer_prop_by_name (new_node, (const guchar *)"column", column.column);
-               e_xml_set_bool_prop_by_name (new_node, (const guchar *)"ascending", column.ascending);
+               e_xml_set_integer_prop_by_name (
+                       new_node, (guchar *) "column", index);
+               e_xml_set_bool_prop_by_name (
+                       new_node, (guchar *) "ascending",
+                       (sort_type == GTK_SORT_ASCENDING));
        }
 
-       for (i = 0; i < sort_count; i++) {
-               ETableSortColumn column;
+       for (ii = 0; ii < sort_count; ii++) {
+               ETableColumnSpecification *column_spec;
+               GtkSortType sort_type;
                xmlNode *new_node;
+               gint index;
 
-               column = e_table_sort_info_sorting_get_nth (sort_info, i);
-               new_node = xmlNewChild (grouping, NULL, (const guchar *)"leaf", NULL);
+               column_spec = e_table_sort_info_sorting_get_nth (
+                       sort_info, ii, &sort_type);
 
-               e_xml_set_integer_prop_by_name (new_node, (const guchar *)"column", column.column);
-               e_xml_set_bool_prop_by_name (new_node, (const guchar *)"ascending", column.ascending);
+               index = e_table_specification_get_column_index (
+                       specification, column_spec);
+
+               if (index < 0) {
+                       g_warn_if_reached ();
+                       continue;
+               }
+
+               new_node = xmlNewChild (
+                       grouping, NULL, (guchar *) "leaf", NULL);
+
+               e_xml_set_integer_prop_by_name (
+                       new_node, (guchar *) "column", index);
+               e_xml_set_bool_prop_by_name (
+                       new_node, (guchar *) "ascending",
+                       (sort_type == GTK_SORT_ASCENDING));
        }
 
+       g_object_unref (specification);
+
        return grouping;
 }
 
diff --git a/e-util/e-table-sort-info.h b/e-util/e-table-sort-info.h
index 64ed864..583feba 100644
--- a/e-util/e-table-sort-info.h
+++ b/e-util/e-table-sort-info.h
@@ -23,9 +23,11 @@
 #ifndef E_TABLE_SORT_INFO_H
 #define E_TABLE_SORT_INFO_H
 
-#include <glib-object.h>
+#include <gtk/gtk.h>
 #include <libxml/tree.h>
 
+#include <e-util/e-table-column-specification.h>
+
 /* Standard GObject macros */
 #define E_TYPE_TABLE_SORT_INFO \
        (e_table_sort_info_get_type ())
@@ -50,17 +52,10 @@ G_BEGIN_DECLS
 /* Avoid a circular dependency. */
 struct _ETableSpecification;
 
-typedef struct _ETableSortColumn ETableSortColumn;
-
 typedef struct _ETableSortInfo ETableSortInfo;
 typedef struct _ETableSortInfoClass ETableSortInfoClass;
 typedef struct _ETableSortInfoPrivate ETableSortInfoPrivate;
 
-struct _ETableSortColumn {
-       guint column : 31;
-       guint ascending : 1;
-};
-
 struct _ETableSortInfo {
        GObject parent;
        ETableSortInfoPrivate *priv;
@@ -74,51 +69,60 @@ struct _ETableSortInfoClass {
        void            (*group_info_changed)   (ETableSortInfo *sort_info);
 };
 
-GType          e_table_sort_info_get_type      (void) G_GNUC_CONST;
-ETableSortInfo *e_table_sort_info_new          (struct _ETableSpecification *specification);
+GType          e_table_sort_info_get_type
+                                       (void) G_GNUC_CONST;
+ETableSortInfo *e_table_sort_info_new  (struct _ETableSpecification *specification);
 struct _ETableSpecification *
                e_table_sort_info_ref_specification
-                                               (ETableSortInfo *sort_info);
-gboolean       e_table_sort_info_get_can_group (ETableSortInfo *sort_info);
-void           e_table_sort_info_set_can_group (ETableSortInfo *sort_info,
-                                                gboolean can_group);
+                                       (ETableSortInfo *sort_info);
+gboolean       e_table_sort_info_get_can_group
+                                       (ETableSortInfo *sort_info);
+void           e_table_sort_info_set_can_group
+                                       (ETableSortInfo *sort_info,
+                                        gboolean can_group);
 guint          e_table_sort_info_grouping_get_count
-                                               (ETableSortInfo *sort_info);
+                                       (ETableSortInfo *sort_info);
 void           e_table_sort_info_grouping_truncate
-                                               (ETableSortInfo *sort_info,
-                                                guint length);
-ETableSortColumn
+                                       (ETableSortInfo *sort_info,
+                                        guint length);
+ETableColumnSpecification *
                e_table_sort_info_grouping_get_nth
-                                               (ETableSortInfo *sort_info,
-                                                guint n);
+                                       (ETableSortInfo *sort_info,
+                                        guint n,
+                                        GtkSortType *out_sort_type);
 void           e_table_sort_info_grouping_set_nth
-                                               (ETableSortInfo *sort_info,
-                                                guint n,
-                                                ETableSortColumn column);
+                                       (ETableSortInfo *sort_info,
+                                        guint n,
+                                        ETableColumnSpecification *spec,
+                                        GtkSortType sort_type);
 
 guint          e_table_sort_info_sorting_get_count
-                                               (ETableSortInfo *sort_info);
+                                       (ETableSortInfo *sort_info);
 void           e_table_sort_info_sorting_remove
-                                               (ETableSortInfo *sort_info,
-                                                guint n);
+                                       (ETableSortInfo *sort_info,
+                                        guint n);
 void           e_table_sort_info_sorting_truncate
-                                               (ETableSortInfo *sort_info,
-                                                guint length);
-ETableSortColumn
+                                       (ETableSortInfo *sort_info,
+                                        guint length);
+ETableColumnSpecification *
                e_table_sort_info_sorting_get_nth
-                                               (ETableSortInfo *sort_info,
-                                                guint n);
+                                       (ETableSortInfo *sort_info,
+                                        guint n,
+                                        GtkSortType *out_sort_type);
 void           e_table_sort_info_sorting_set_nth
-                                               (ETableSortInfo *sort_info,
-                                                guint n,
-                                                ETableSortColumn column);
+                                       (ETableSortInfo *sort_info,
+                                        guint n,
+                                        ETableColumnSpecification *spec,
+                                        GtkSortType sort_type);
 void           e_table_sort_info_load_from_node
-                                               (ETableSortInfo *sort_info,
-                                                xmlNode *node,
-                                                gdouble state_version);
-xmlNode *      e_table_sort_info_save_to_node  (ETableSortInfo *sort_info,
-                                                xmlNode *parent);
-ETableSortInfo *e_table_sort_info_duplicate    (ETableSortInfo *sort_info);
+                                       (ETableSortInfo *sort_info,
+                                        xmlNode *node,
+                                        gdouble state_version);
+xmlNode *      e_table_sort_info_save_to_node
+                                       (ETableSortInfo *sort_info,
+                                        xmlNode *parent);
+ETableSortInfo *e_table_sort_info_duplicate
+                                       (ETableSortInfo *sort_info);
 
 G_END_DECLS
 
diff --git a/e-util/e-table-sorter.c b/e-util/e-table-sorter.c
index 1342326..d8e50db 100644
--- a/e-util/e-table-sorter.c
+++ b/e-util/e-table-sorter.c
@@ -136,24 +136,36 @@ table_sorter_sort (ETableSorter *table_sorter)
        qd.cmp_cache = e_table_sorting_utils_create_cmp_cache ();
 
        for (j = 0; j < cols; j++) {
-               ETableSortColumn column;
+               ETableColumnSpecification *spec;
                ETableCol *col;
+               GtkSortType sort_type;
 
                if (j < group_cols)
-                       column = e_table_sort_info_grouping_get_nth (table_sorter->sort_info, j);
+                       spec = e_table_sort_info_grouping_get_nth (
+                               table_sorter->sort_info,
+                               j, &sort_type);
                else
-                       column = e_table_sort_info_sorting_get_nth (table_sorter->sort_info, j - group_cols);
-
-               col = e_table_header_get_column_by_col_idx (table_sorter->full_header, column.column);
-               if (col == NULL)
-                       col = e_table_header_get_column (table_sorter->full_header, e_table_header_count 
(table_sorter->full_header) - 1);
+                       spec = e_table_sort_info_sorting_get_nth (
+                               table_sorter->sort_info,
+                               j - group_cols, &sort_type);
+
+               col = e_table_header_get_column_by_spec (
+                       table_sorter->full_header, spec);
+               if (col == NULL) {
+                       gint last = e_table_header_count (
+                               table_sorter->full_header) - 1;
+                       col = e_table_header_get_column (
+                               table_sorter->full_header, last);
+               }
 
                for (i = 0; i < rows; i++) {
-                       qd.vals[i * cols + j] = e_table_model_value_at (table_sorter->source, 
col->spec->model_col, i);
+                       qd.vals[i * cols + j] = e_table_model_value_at (
+                               table_sorter->source,
+                               col->spec->model_col, i);
                }
 
                qd.compare[j] = col->compare;
-               qd.ascending[j] = column.ascending;
+               qd.ascending[j] = (sort_type == GTK_SORT_ASCENDING);
        }
 
        g_qsort_with_data (table_sorter->sorted, rows, sizeof (gint), qsort_callback, &qd);
diff --git a/e-util/e-table-sorting-utils.c b/e-util/e-table-sorting-utils.c
index a8c5bcd..4e04134 100644
--- a/e-util/e-table-sorting-utils.c
+++ b/e-util/e-table-sorting-utils.c
@@ -48,10 +48,13 @@ etsu_compare (ETableModel *source,
        GtkSortType sort_type = GTK_SORT_ASCENDING;
 
        for (j = 0; j < sort_count; j++) {
-               ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j);
+               ETableColumnSpecification *spec;
                ETableCol *col;
 
-               col = e_table_header_get_column_by_col_idx (full_header, column.column);
+               spec = e_table_sort_info_sorting_get_nth (
+                       sort_info, j, &sort_type);
+
+               col = e_table_header_get_column_by_spec (full_header, spec);
                if (col == NULL) {
                        gint last = e_table_header_count (full_header) - 1;
                        col = e_table_header_get_column (full_header, last);
@@ -63,10 +66,6 @@ etsu_compare (ETableModel *source,
                        e_table_model_value_at (
                                source, col->spec->compare_col, row2),
                        cmp_cache);
-               if (column.ascending)
-                       sort_type = GTK_SORT_ASCENDING;
-               else
-                       sort_type = GTK_SORT_DESCENDING;
                if (comp_val != 0)
                        break;
        }
@@ -163,10 +162,13 @@ e_table_sorting_utils_sort (ETableModel *source,
        closure.cmp_cache = e_table_sorting_utils_create_cmp_cache ();
 
        for (j = 0; j < cols; j++) {
-               ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j);
+               ETableColumnSpecification *spec;
                ETableCol *col;
 
-               col = e_table_header_get_column_by_col_idx (full_header, column.column);
+               spec = e_table_sort_info_sorting_get_nth (
+                       sort_info, j, &closure.sort_type[j]);
+
+               col = e_table_header_get_column_by_spec (full_header, spec);
                if (col == NULL) {
                        gint last = e_table_header_count (full_header) - 1;
                        col = e_table_header_get_column (full_header, last);
@@ -176,10 +178,6 @@ e_table_sorting_utils_sort (ETableModel *source,
                        closure.vals[map_table[i] * cols + j] = e_table_model_value_at (source, 
col->spec->compare_col, map_table[i]);
                }
                closure.compare[j] = col->compare;
-               if (column.ascending)
-                       closure.sort_type[j] = GTK_SORT_ASCENDING;
-               else
-                       closure.sort_type[j] = GTK_SORT_DESCENDING;
        }
 
        g_qsort_with_data (
@@ -205,10 +203,13 @@ e_table_sorting_utils_affects_sort (ETableSortInfo *sort_info,
        cols = e_table_sort_info_sorting_get_count (sort_info);
 
        for (j = 0; j < cols; j++) {
-               ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j);
+               ETableColumnSpecification *spec;
                ETableCol *col;
 
-               col = e_table_header_get_column_by_col_idx (full_header, column.column);
+               spec = e_table_sort_info_sorting_get_nth (
+                       sort_info, j, NULL);
+
+               col = e_table_header_get_column_by_spec (full_header, spec);
                if (col == NULL) {
                        gint last = e_table_header_count (full_header) - 1;
                        col = e_table_header_get_column (full_header, last);
@@ -291,10 +292,13 @@ etsu_tree_compare (ETreeModel *source,
        GtkSortType sort_type = GTK_SORT_ASCENDING;
 
        for (j = 0; j < sort_count; j++) {
-               ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j);
+               ETableColumnSpecification *spec;
                ETableCol *col;
 
-               col = e_table_header_get_column_by_col_idx (full_header, column.column);
+               spec = e_table_sort_info_sorting_get_nth (
+                       sort_info, j, &sort_type);
+
+               col = e_table_header_get_column_by_spec (full_header, spec);
                if (col == NULL) {
                        gint last = e_table_header_count (full_header) - 1;
                        col = e_table_header_get_column (full_header, last);
@@ -306,10 +310,6 @@ etsu_tree_compare (ETreeModel *source,
                        e_tree_model_value_at (
                                source, path2, col->spec->compare_col),
                        cmp_cache);
-               if (column.ascending)
-                       sort_type = GTK_SORT_ASCENDING;
-               else
-                       sort_type = GTK_SORT_DESCENDING;
                if (comp_val != 0)
                        break;
        }
@@ -358,10 +358,13 @@ e_table_sorting_utils_tree_sort (ETreeModel *source,
        closure.cmp_cache = e_table_sorting_utils_create_cmp_cache ();
 
        for (j = 0; j < cols; j++) {
-               ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, j);
+               ETableColumnSpecification *spec;
                ETableCol *col;
 
-               col = e_table_header_get_column_by_col_idx (full_header, column.column);
+               spec = e_table_sort_info_sorting_get_nth (
+                       sort_info, j, &closure.sort_type[j]);
+
+               col = e_table_header_get_column_by_spec (full_header, spec);
                if (col == NULL) {
                        gint last = e_table_header_count (full_header) - 1;
                        col = e_table_header_get_column (full_header, last);
@@ -371,10 +374,6 @@ e_table_sorting_utils_tree_sort (ETreeModel *source,
                        closure.vals[i * cols + j] = e_tree_model_sort_value_at (source, map_table[i], 
col->spec->compare_col);
                }
                closure.compare[j] = col->compare;
-               if (column.ascending)
-                       closure.sort_type[j] = GTK_SORT_ASCENDING;
-               else
-                       closure.sort_type[j] = GTK_SORT_DESCENDING;
        }
 
        map = g_new (int, count);
diff --git a/e-util/e-table-utils.c b/e-util/e-table-utils.c
index 040e5d3..a3b8b92 100644
--- a/e-util/e-table-utils.c
+++ b/e-util/e-table-utils.c
@@ -174,37 +174,33 @@ e_table_util_calculate_current_search_col (ETableHeader *header,
        count = e_table_sort_info_grouping_get_count (sort_info);
 
        for (i = 0; i < count; i++) {
-               ETableSortColumn column;
+               ETableColumnSpecification *spec;
 
-               column = e_table_sort_info_grouping_get_nth (sort_info, i);
+               spec = e_table_sort_info_grouping_get_nth (sort_info, i, NULL);
+               col = e_table_header_get_column_by_spec (full_header, spec);
 
-               col = e_table_header_get_column (full_header, column.column);
-
-               if (col && col->search)
-                       break;
+               if (col != NULL && col->search)
+                       return col;
 
                col = NULL;
        }
 
-       if (col == NULL) {
-               count = e_table_sort_info_sorting_get_count (sort_info);
-               for (i = 0; i < count; i++) {
-                       ETableSortColumn column;
-
-                       column = e_table_sort_info_sorting_get_nth (sort_info, i);
+       count = e_table_sort_info_sorting_get_count (sort_info);
+       for (i = 0; i < count; i++) {
+               ETableColumnSpecification *spec;
 
-                       col = e_table_header_get_column (full_header, column.column);
+               spec = e_table_sort_info_sorting_get_nth (sort_info, i, NULL);
+               col = e_table_header_get_column_by_spec (full_header, spec);
 
-                       if (col && col->search)
-                               break;
+               if (col != NULL && col->search)
+                       return col;
 
-                       col = NULL;
-               }
+               col = NULL;
        }
 
-       if (col == NULL && always_search) {
-               col = e_table_header_prioritized_column_selected (header, check_col, NULL);
-       }
+       if (always_search)
+               col = e_table_header_prioritized_column_selected (
+                       header, check_col, NULL);
 
        return col;
 }
diff --git a/mail/message-list.c b/mail/message-list.c
index 7ce7412..cf8f99e 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -5053,7 +5053,7 @@ message_list_set_search (MessageList *message_list,
 
 struct sort_column_data {
        ETableCol *col;
-       gboolean ascending;
+       GtkSortType sort_type;
 };
 
 struct sort_message_info_data {
@@ -5128,7 +5128,7 @@ cmp_array_uids (gconstpointer a,
                        res = v1 == NULL ? -1 : 1;
                }
 
-               if (!scol->ascending)
+               if (scol->sort_type == GTK_SORT_DESCENDING)
                        res = res * (-1);
        }
 
@@ -5198,15 +5198,19 @@ ml_sort_uids_by_tree (MessageList *message_list,
             i < len
             && !g_cancellable_is_cancelled (cancellable);
             i++) {
-               ETableSortColumn scol;
-               struct sort_column_data *data = g_new0 (struct sort_column_data, 1);
+               ETableColumnSpecification *spec;
+               struct sort_column_data *data;
 
-               scol = e_table_sort_info_sorting_get_nth (sort_info, i);
+               data = g_new0 (struct sort_column_data, 1);
 
-               data->ascending = scol.ascending;
-               data->col = e_table_header_get_column_by_col_idx (full_header, scol.column);
-               if (data->col == NULL)
-                       data->col = e_table_header_get_column (full_header, e_table_header_count 
(full_header) - 1);
+               spec = e_table_sort_info_sorting_get_nth (
+                       sort_info, i, &data->sort_type);
+
+               data->col = e_table_header_get_column_by_spec (full_header, spec);
+               if (data->col == NULL) {
+                       gint last = e_table_header_count (full_header) - 1;
+                       data->col = e_table_header_get_column (full_header, last);
+               }
 
                g_ptr_array_add (sort_data.sort_columns, data);
        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]