[evolution] Bug 692557 - Add option to always sort thread children ascending



commit 78ed4ca15e7e04c88cb5070f4b85baa2bdc8b549
Author: Milan Crha <mcrha redhat com>
Date:   Fri Apr 24 10:37:54 2015 +0200

    Bug 692557 - Add option to always sort thread children ascending

 data/org.gnome.evolution.mail.gschema.xml.in |    5 ++
 e-util/e-table-sort-info.c                   |   10 ++-
 e-util/e-tree-table-adapter.c                |   98 +++++++++++++++++++++++++-
 e-util/e-tree-table-adapter.h                |    5 ++
 e-util/e-tree.c                              |   47 ++++++++++++-
 e-util/e-tree.h                              |    5 ++
 mail/message-list.c                          |    9 ++-
 modules/settings/e-settings-message-list.c   |    5 ++
 8 files changed, 175 insertions(+), 9 deletions(-)
---
diff --git a/data/org.gnome.evolution.mail.gschema.xml.in b/data/org.gnome.evolution.mail.gschema.xml.in
index 33103ab..d1b153c 100644
--- a/data/org.gnome.evolution.mail.gschema.xml.in
+++ b/data/org.gnome.evolution.mail.gschema.xml.in
@@ -368,6 +368,11 @@
       <_summary>Whether sort threads based on latest message in that thread</_summary>
       <_description>This setting specifies whether the threads should be sorted based on latest message in 
each thread, rather than by message's date. Evolution requires a restart.</_description>
     </key>
+    <key name="thread-children-ascending" type="b">
+      <default>true</default>
+      <_summary>Whether sort thread children always ascending</_summary>
+      <_description>This setting specifies whether the thread children should be sorted always ascending, 
rather than using the same sort order as in the thread root level.</_description>
+    </key>
     <key name="sort-accounts-alpha" type="b">
       <default>true</default>
       <_summary>Sort accounts alphabetically in a folder tree</_summary>
diff --git a/e-util/e-table-sort-info.c b/e-util/e-table-sort-info.c
index caf571f..ae1806d 100644
--- a/e-util/e-table-sort-info.c
+++ b/e-util/e-table-sort-info.c
@@ -565,9 +565,12 @@ e_table_sort_info_grouping_set_nth (ETableSortInfo *sort_info,
        g_array_set_size (array, MAX (n + 1, array->len));
        column_data = &g_array_index (array, ColumnData, n);
 
+       /* In case it's setting the same specification, to not free it */
+       g_object_ref (spec);
+
        column_data_clear (column_data);
 
-       column_data->column_spec = g_object_ref (spec);
+       column_data->column_spec = spec;
        column_data->sort_type = sort_type;
 
        g_signal_emit (sort_info, signals[GROUP_INFO_CHANGED], 0);
@@ -684,9 +687,12 @@ e_table_sort_info_sorting_set_nth (ETableSortInfo *sort_info,
        g_array_set_size (array, MAX (n + 1, array->len));
        column_data = &g_array_index (array, ColumnData, n);
 
+       /* In case it's setting the same specification, to not free it */
+       g_object_ref (spec);
+
        column_data_clear (column_data);
 
-       column_data->column_spec = g_object_ref (spec);
+       column_data->column_spec = spec;
        column_data->sort_type = sort_type;
 
        g_signal_emit (sort_info, signals[SORT_INFO_CHANGED], 0);
diff --git a/e-util/e-tree-table-adapter.c b/e-util/e-tree-table-adapter.c
index b81e385..6fa3974 100644
--- a/e-util/e-tree-table-adapter.c
+++ b/e-util/e-tree-table-adapter.c
@@ -65,6 +65,8 @@ struct _ETreeTableAdapterPrivate {
 
        ETableSortInfo *sort_info;
        gulong sort_info_changed_handler_id;
+       ETableSortInfo *children_sort_info;
+       gboolean sort_children_ascending;
 
        ETableHeader *header;
 
@@ -88,7 +90,8 @@ enum {
        PROP_0,
        PROP_HEADER,
        PROP_SORT_INFO,
-       PROP_SOURCE_MODEL
+       PROP_SOURCE_MODEL,
+       PROP_SORT_CHILDREN_ASCENDING
 };
 
 enum {
@@ -217,8 +220,36 @@ resort_node (ETreeTableAdapter *etta,
             path = e_tree_model_node_get_next (etta->priv->source_model, path), i++)
                paths[i] = path;
 
-       if (count > 1 && sort_needed)
-               e_table_sorting_utils_tree_sort (etta->priv->source_model, etta->priv->sort_info, 
etta->priv->header, paths, count);
+       if (count > 1 && sort_needed) {
+               ETableSortInfo *use_sort_info;
+
+               use_sort_info = etta->priv->sort_info;
+
+               if (etta->priv->sort_children_ascending && gnode->parent) {
+                       if (!etta->priv->children_sort_info) {
+                               gint len;
+
+                               etta->priv->children_sort_info = e_table_sort_info_duplicate 
(etta->priv->sort_info);
+
+                               len = e_table_sort_info_sorting_get_count (etta->priv->children_sort_info);
+
+                               for (i = 0; i < len; i++) {
+                                       ETableColumnSpecification *spec;
+                                       GtkSortType sort_type;
+
+                                       spec = e_table_sort_info_sorting_get_nth 
(etta->priv->children_sort_info, i, &sort_type);
+                                       if (spec) {
+                                               if (sort_type == GTK_SORT_DESCENDING)
+                                                       e_table_sort_info_sorting_set_nth 
(etta->priv->children_sort_info, i, spec, GTK_SORT_ASCENDING);
+                                       }
+                               }
+                       }
+
+                       use_sort_info = etta->priv->children_sort_info;
+               }
+
+               e_table_sorting_utils_tree_sort (etta->priv->source_model, use_sort_info, etta->priv->header, 
paths, count);
+       }
 
        prev = NULL;
        for (i = 0; i < count; i++) {
@@ -525,6 +556,8 @@ static void
 tree_table_adapter_sort_info_changed_cb (ETableSortInfo *sort_info,
                                          ETreeTableAdapter *etta)
 {
+       g_clear_object (&etta->priv->children_sort_info);
+
        if (!etta->priv->root)
                return;
 
@@ -680,6 +713,12 @@ tree_table_adapter_set_property (GObject *object,
                                E_TREE_TABLE_ADAPTER (object),
                                g_value_get_object (value));
                        return;
+
+               case PROP_SORT_CHILDREN_ASCENDING:
+                       e_tree_table_adapter_set_sort_children_ascending (
+                               E_TREE_TABLE_ADAPTER (object),
+                               g_value_get_boolean (value));
+                       return;
        }
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -712,6 +751,13 @@ tree_table_adapter_get_property (GObject *object,
                                e_tree_table_adapter_get_source_model (
                                E_TREE_TABLE_ADAPTER (object)));
                        return;
+
+               case PROP_SORT_CHILDREN_ASCENDING:
+                       g_value_set_boolean (
+                               value,
+                               e_tree_table_adapter_get_sort_children_ascending (
+                               E_TREE_TABLE_ADAPTER (object)));
+                       return;
        }
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -775,6 +821,7 @@ tree_table_adapter_dispose (GObject *object)
 
        g_clear_object (&priv->source_model);
        g_clear_object (&priv->sort_info);
+       g_clear_object (&priv->children_sort_info);
        g_clear_object (&priv->header);
 
        /* Chain up to parent's dispose() method. */
@@ -1041,6 +1088,18 @@ e_tree_table_adapter_class_init (ETreeTableAdapterClass *class)
                        G_PARAM_CONSTRUCT_ONLY |
                        G_PARAM_STATIC_STRINGS));
 
+       g_object_class_install_property (
+               object_class,
+               PROP_SORT_CHILDREN_ASCENDING,
+               g_param_spec_boolean (
+                       "sort-children-ascending",
+                       "Sort Children Ascending",
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       G_PARAM_STATIC_STRINGS));
+
        signals[SORTING_CHANGED] = g_signal_new (
                "sorting_changed",
                G_OBJECT_CLASS_TYPE (object_class),
@@ -1153,6 +1212,8 @@ e_tree_table_adapter_set_sort_info (ETreeTableAdapter *etta,
                etta->priv->sort_info_changed_handler_id = handler_id;
        }
 
+       g_clear_object (&etta->priv->children_sort_info);
+
        g_object_notify (G_OBJECT (etta), "sort-info");
 
        if (etta->priv->root == NULL)
@@ -1164,6 +1225,37 @@ e_tree_table_adapter_set_sort_info (ETreeTableAdapter *etta,
        e_table_model_changed (E_TABLE_MODEL (etta));
 }
 
+gboolean
+e_tree_table_adapter_get_sort_children_ascending (ETreeTableAdapter *etta)
+{
+       g_return_val_if_fail (E_IS_TREE_TABLE_ADAPTER (etta), FALSE);
+
+       return etta->priv->sort_children_ascending;
+}
+
+void
+e_tree_table_adapter_set_sort_children_ascending (ETreeTableAdapter *etta,
+                                                 gboolean sort_children_ascending)
+{
+       g_return_if_fail (E_IS_TREE_TABLE_ADAPTER (etta));
+
+       if ((etta->priv->sort_children_ascending ? 1 : 0) == (sort_children_ascending ? 1 : 0))
+               return;
+
+       etta->priv->sort_children_ascending = sort_children_ascending;
+       g_clear_object (&etta->priv->children_sort_info);
+
+       g_object_notify (G_OBJECT (etta), "sort-children-ascending");
+
+       if (!etta->priv->root)
+               return;
+
+       e_table_model_pre_change (E_TABLE_MODEL (etta));
+       resort_node (etta, etta->priv->root, TRUE);
+       fill_map (etta, 0, etta->priv->root);
+       e_table_model_changed (E_TABLE_MODEL (etta));
+}
+
 ETreeModel *
 e_tree_table_adapter_get_source_model (ETreeTableAdapter *etta)
 {
diff --git a/e-util/e-tree-table-adapter.h b/e-util/e-tree-table-adapter.h
index 57005a8..d9926f5 100644
--- a/e-util/e-tree-table-adapter.h
+++ b/e-util/e-tree-table-adapter.h
@@ -81,6 +81,11 @@ ETableSortInfo *e_tree_table_adapter_get_sort_info
 void           e_tree_table_adapter_set_sort_info
                                                (ETreeTableAdapter *etta,
                                                 ETableSortInfo *sort_info);
+gboolean       e_tree_table_adapter_get_sort_children_ascending
+                                               (ETreeTableAdapter *etta);
+void           e_tree_table_adapter_set_sort_children_ascending
+                                               (ETreeTableAdapter *etta,
+                                                gboolean sort_children_ascending);
 ETreeModel *   e_tree_table_adapter_get_source_model
                                                (ETreeTableAdapter *etta);
 
diff --git a/e-util/e-tree.c b/e-util/e-tree.c
index 89076a1..502967a 100644
--- a/e-util/e-tree.c
+++ b/e-util/e-tree.c
@@ -103,7 +103,8 @@ enum {
        PROP_HADJUSTMENT,
        PROP_VADJUSTMENT,
        PROP_HSCROLL_POLICY,
-       PROP_VSCROLL_POLICY
+       PROP_VSCROLL_POLICY,
+       PROP_SORT_CHILDREN_ASCENDING
 };
 
 enum {
@@ -208,6 +209,7 @@ struct _ETreePrivate {
        gboolean is_dragging;
 
        gboolean grouped_view;
+       gboolean sort_children_ascending;
 };
 
 static guint signals[LAST_SIGNAL];
@@ -1575,6 +1577,9 @@ et_connect_to_etta (ETree *tree)
                tree->priv->etta, "model_rows_deleted",
                G_CALLBACK (et_table_rows_deleted), tree);
 
+       g_object_bind_property (tree, "sort-children-ascending",
+               tree->priv->etta, "sort-children-ascending",
+               G_BINDING_DEFAULT);
 }
 
 static gboolean
@@ -1872,6 +1877,10 @@ et_get_property (GObject *object,
                        g_value_set_enum (value, 0);
                break;
 
+       case PROP_SORT_CHILDREN_ASCENDING:
+               g_value_set_boolean (value, e_tree_get_sort_children_ascending (tree));
+               break;
+
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
@@ -1981,6 +1990,10 @@ et_set_property (GObject *object,
                                G_OBJECT (tree->priv->table_canvas),
                                "vscroll-policy", value);
                break;
+
+       case PROP_SORT_CHILDREN_ASCENDING:
+               e_tree_set_sort_children_ascending (tree, g_value_get_boolean (value));
+               break;
        }
 }
 
@@ -3162,6 +3175,16 @@ e_tree_class_init (ETreeClass *class)
                        FALSE,
                        G_PARAM_READWRITE));
 
+       g_object_class_install_property (
+               object_class,
+               PROP_SORT_CHILDREN_ASCENDING,
+               g_param_spec_boolean (
+                       "sort-children-ascending",
+                       "Sort Children Ascending",
+                       "Always sort children tree nodes ascending",
+                       FALSE,
+                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
        gtk_widget_class_install_style_property (
                widget_class,
                g_param_spec_int (
@@ -3365,3 +3388,25 @@ e_tree_get_grouped_view (ETree *tree)
 
        return tree->priv->grouped_view;
 }
+
+gboolean
+e_tree_get_sort_children_ascending (ETree *tree)
+{
+       g_return_val_if_fail (E_IS_TREE (tree), FALSE);
+
+       return tree->priv->sort_children_ascending;
+}
+
+void
+e_tree_set_sort_children_ascending (ETree *tree,
+                                   gboolean sort_children_ascending)
+{
+       g_return_if_fail (E_IS_TREE (tree));
+
+       if ((tree->priv->sort_children_ascending ? 1 : 0) == (sort_children_ascending ? 1 : 0))
+               return;
+
+       tree->priv->sort_children_ascending = sort_children_ascending;
+
+       g_object_notify (G_OBJECT (tree), "sort-children-ascending");
+}
diff --git a/e-util/e-tree.h b/e-util/e-tree.h
index a10ea95..35e20c8 100644
--- a/e-util/e-tree.h
+++ b/e-util/e-tree.h
@@ -256,6 +256,11 @@ gboolean   e_tree_is_editing               (ETree *tree);
 gboolean       e_tree_get_grouped_view         (ETree *tree);
 void           e_tree_set_grouped_view         (ETree *tree,
                                                 gboolean grouped_view);
+gboolean       e_tree_get_sort_children_ascending
+                                               (ETree *tree);
+void           e_tree_set_sort_children_ascending
+                                               (ETree *tree,
+                                                gboolean sort_children_ascending);
 
 G_END_DECLS
 
diff --git a/mail/message-list.c b/mail/message-list.c
index d9b5372..905d978 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -3099,6 +3099,7 @@ message_list_sort_value_at (ETreeModel *tree_model,
                             gint col)
 {
        MessageList *message_list;
+       GNode *path_node;
        struct LatestData ld;
        gint64 *res;
 
@@ -3107,18 +3108,20 @@ message_list_sort_value_at (ETreeModel *tree_model,
        if (!(col == COL_SENT || col == COL_RECEIVED))
                return e_tree_model_value_at (tree_model, path, col);
 
-       if (G_NODE_IS_ROOT ((GNode *) path))
+       path_node = (GNode *) path;
+
+       if (G_NODE_IS_ROOT (path_node))
                return NULL;
 
        ld.sent = (col == COL_SENT);
        ld.latest = 0;
 
        latest_foreach (tree_model, path, &ld);
-       if (message_list->priv->thread_latest)
+       if (message_list->priv->thread_latest && (!e_tree_get_sort_children_ascending (E_TREE (message_list)) 
||
+           !path_node || !path_node->parent || !path_node->parent->parent))
                e_tree_model_node_traverse (
                        tree_model, path, latest_foreach, &ld);
 
-
        res = g_new0 (gint64, 1);
        *res = (gint64) ld.latest;
 
diff --git a/modules/settings/e-settings-message-list.c b/modules/settings/e-settings-message-list.c
index 5ea0df5..9725455 100644
--- a/modules/settings/e-settings-message-list.c
+++ b/modules/settings/e-settings-message-list.c
@@ -61,6 +61,11 @@ settings_message_list_constructed (GObject *object)
                message_list, "thread-subject",
                G_SETTINGS_BIND_GET);
 
+       g_settings_bind (
+               settings, "thread-children-ascending",
+               message_list, "sort-children-ascending",
+               G_SETTINGS_BIND_GET);
+
        /* This setting only controls the initial message list
         * state when in threaded mode, so just apply it here. */
        message_list_set_expanded_default (


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