[evolution] ETree/ETable: Allow easier adding of columns for sorting



commit 3a91092b4af34c9429adf92dc3af73cc3d85ddb4
Author: Milan Crha <mcrha redhat com>
Date:   Tue Feb 25 11:09:34 2014 +0100

    ETree/ETable: Allow easier adding of columns for sorting
    
    This extends behaviour of left-clicking column header which is not
    used for sorting yet in an ETree/ETable in a way:
    a) alone left-click behaves like before, all current sorting is dropped
       and the ETree/ETable is sorted only by that column
    b) left-click with pressed Ctrl key adds the column as the first to sort by
    c) left-click with pressed Ctrl+Shift adds the column as the last to sort by

 e-util/e-table-header-item.c            |   39 ++++++++++++++++++------
 e-util/e-table-header-item.h            |    9 +++++-
 e-util/e-table-sort-info.c              |   49 +++++++++++++++++++++++++++++++
 e-util/e-table-sort-info.h              |    5 +++
 e-util/gal-a11y-e-table-column-header.c |    2 +-
 5 files changed, 92 insertions(+), 12 deletions(-)
---
diff --git a/e-util/e-table-header-item.c b/e-util/e-table-header-item.c
index 3b843ad..06c3f7e 100644
--- a/e-util/e-table-header-item.c
+++ b/e-util/e-table-header-item.c
@@ -1659,7 +1659,7 @@ sort_by_id (GtkWidget *menu_item,
        if (clearfirst)
                e_table_sort_info_sorting_truncate (ethi->sort_info, 0);
 
-       ethi_change_sort_state (ethi, ecol);
+       ethi_change_sort_state (ethi, ecol, E_TABLE_HEADER_ITEM_SORT_FLAG_NONE);
 }
 
 static void
@@ -1793,7 +1793,8 @@ ethi_button_pressed (ETableHeaderItem *ethi,
 
 void
 ethi_change_sort_state (ETableHeaderItem *ethi,
-                        ETableCol *col)
+                        ETableCol *col,
+                       ETableHeaderItemSortFlag flag)
 {
        ETableColumnSpecification *col_spec = NULL;
        gint length;
@@ -1868,11 +1869,21 @@ ethi_change_sort_state (ETableHeaderItem *ethi,
        }
 
        if (!found && col_spec != NULL) {
-               e_table_sort_info_sorting_truncate (ethi->sort_info, 0);
+               if (flag == E_TABLE_HEADER_ITEM_SORT_FLAG_NONE) {
+                       e_table_sort_info_sorting_truncate (ethi->sort_info, 0);
+                       e_table_sort_info_sorting_set_nth (
+                               ethi->sort_info, 0,
+                               col_spec, GTK_SORT_ASCENDING);
+               } else {
+                       guint index = 0;
 
-               e_table_sort_info_sorting_set_nth (
-                       ethi->sort_info, 0,
-                       col_spec, GTK_SORT_ASCENDING);
+                       if (flag == E_TABLE_HEADER_ITEM_SORT_FLAG_ADD_AS_LAST)
+                               index = e_table_sort_info_sorting_get_count (ethi->sort_info);
+
+                       e_table_sort_info_sorting_insert (
+                               ethi->sort_info, index,
+                               col_spec, GTK_SORT_ASCENDING);
+               }
        }
 }
 
@@ -1895,6 +1906,7 @@ ethi_event (GnomeCanvasItem *item,
        gdouble event_x_win = 0;
        gdouble event_y_win = 0;
        guint32 event_time;
+       ETableHeaderItemSortFlag sort_flag = E_TABLE_HEADER_ITEM_SORT_FLAG_NONE;
 
        /* Don't fetch the device here.  GnomeCanvas frequently emits
         * synthesized events, and calling gdk_event_get_device() on them
@@ -1905,6 +1917,13 @@ ethi_event (GnomeCanvasItem *item,
        gdk_event_get_state (event, &event_state);
        event_time = gdk_event_get_time (event);
 
+       if ((event_state & GDK_CONTROL_MASK) != 0) {
+               if ((event_state & GDK_SHIFT_MASK) != 0)
+                       sort_flag = E_TABLE_HEADER_ITEM_SORT_FLAG_ADD_AS_LAST;
+               else
+                       sort_flag = E_TABLE_HEADER_ITEM_SORT_FLAG_ADD_AS_FIRST;
+       }
+
        switch (event->type) {
        case GDK_ENTER_NOTIFY:
                convert (canvas, event_x_win, event_y_win, &x, &y);
@@ -2030,7 +2049,7 @@ ethi_event (GnomeCanvasItem *item,
 
                        col = ethi_find_col_by_x (ethi, event_x_win);
                        ecol = e_table_header_get_column (ethi->eth, col);
-                       ethi_change_sort_state (ethi, ecol);
+                       ethi_change_sort_state (ethi, ecol, sort_flag);
                }
 
                if (needs_ungrab)
@@ -2069,7 +2088,7 @@ ethi_event (GnomeCanvasItem *item,
                        ETableCol *ecol;
 
                        ecol = e_table_header_get_column (ethi->eth, ethi->selected_col);
-                       ethi_change_sort_state (ethi, ecol);
+                       ethi_change_sort_state (ethi, ecol, sort_flag);
                } else if ((event_keyval == GDK_KEY_Right) ||
                                (event_keyval == GDK_KEY_KP_Right)) {
                        ETableCol *ecol;
@@ -2080,7 +2099,7 @@ ethi_event (GnomeCanvasItem *item,
                        else
                                ethi->selected_col++;
                        ecol = e_table_header_get_column (ethi->eth, ethi->selected_col);
-                       ethi_change_sort_state (ethi, ecol);
+                       ethi_change_sort_state (ethi, ecol, sort_flag);
                } else if ((event_keyval == GDK_KEY_Left) ||
                           (event_keyval == GDK_KEY_KP_Left)) {
                        ETableCol *ecol;
@@ -2091,7 +2110,7 @@ ethi_event (GnomeCanvasItem *item,
                        else
                                ethi->selected_col--;
                        ecol = e_table_header_get_column (ethi->eth, ethi->selected_col);
-                       ethi_change_sort_state (ethi, ecol);
+                       ethi_change_sort_state (ethi, ecol, sort_flag);
                }
                break;
 
diff --git a/e-util/e-table-header-item.h b/e-util/e-table-header-item.h
index 8ad740a..effc580 100644
--- a/e-util/e-table-header-item.h
+++ b/e-util/e-table-header-item.h
@@ -56,6 +56,12 @@
 
 G_BEGIN_DECLS
 
+typedef enum {
+       E_TABLE_HEADER_ITEM_SORT_FLAG_NONE = 0,
+       E_TABLE_HEADER_ITEM_SORT_FLAG_ADD_AS_FIRST = (1 << 0),
+       E_TABLE_HEADER_ITEM_SORT_FLAG_ADD_AS_LAST = (1 << 1)
+} ETableHeaderItemSortFlag;
+
 typedef struct _ETableHeaderItem ETableHeaderItem;
 typedef struct _ETableHeaderItemClass ETableHeaderItemClass;
 
@@ -140,7 +146,8 @@ struct _ETableHeaderItemClass {
 
 GType          e_table_header_item_get_type    (void) G_GNUC_CONST;
 void           ethi_change_sort_state          (ETableHeaderItem *ethi,
-                                                ETableCol *col);
+                                                ETableCol *col,
+                                                ETableHeaderItemSortFlag flag);
 
 G_END_DECLS
 
diff --git a/e-util/e-table-sort-info.c b/e-util/e-table-sort-info.c
index 815897b..caf571f 100644
--- a/e-util/e-table-sort-info.c
+++ b/e-util/e-table-sort-info.c
@@ -693,6 +693,55 @@ e_table_sort_info_sorting_set_nth (ETableSortInfo *sort_info,
 }
 
 /**
+ * @sort_info: an #ETableSortInfo
+ * @n: Index to insert to.
+ * @spec: an #ETableColumnSpecification
+ * @sort_type: a #GtkSortType
+ *
+ * Inserts the sorting criteria for index @n to @spec and @sort_type.
+ *
+ * Since: 3.12
+ **/
+void
+e_table_sort_info_sorting_insert (ETableSortInfo *sort_info,
+                                 guint n,
+                                 ETableColumnSpecification *spec,
+                                 GtkSortType sort_type)
+{
+       GArray *array;
+       ColumnData *column_data, tmp;
+
+       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;
+       if (array->len == 0) {
+               e_table_sort_info_sorting_set_nth (sort_info, 0, spec, sort_type);
+               return;
+       }
+
+       if ((gint) n == -1)
+               n = 0;
+       else if (n > array->len)
+               n = array->len;
+
+       tmp.column_spec = NULL;
+       tmp.sort_type = sort_type;
+       column_data = &tmp;
+
+       if (n == array->len)
+               g_array_append_val (array, column_data);
+       else
+               g_array_insert_val (array, n, column_data);
+
+       column_data = &g_array_index (array, ColumnData, n);
+       column_data->column_spec = g_object_ref (spec);
+       column_data->sort_type = sort_type;
+
+       g_signal_emit (sort_info, signals[SORT_INFO_CHANGED], 0);
+}
+
+/**
  * e_table_sort_info_load_from_node:
  * @sort_info: an #ETableSortInfo
  * @node: pointer to the xmlNode that describes the sorting and grouping information
diff --git a/e-util/e-table-sort-info.h b/e-util/e-table-sort-info.h
index 1b11911..47ab851 100644
--- a/e-util/e-table-sort-info.h
+++ b/e-util/e-table-sort-info.h
@@ -119,6 +119,11 @@ void               e_table_sort_info_sorting_set_nth
                                         guint n,
                                         ETableColumnSpecification *spec,
                                         GtkSortType sort_type);
+void           e_table_sort_info_sorting_insert
+                                       (ETableSortInfo *sort_info,
+                                        guint n,
+                                        ETableColumnSpecification *spec,
+                                        GtkSortType sort_type);
 void           e_table_sort_info_load_from_node
                                        (ETableSortInfo *sort_info,
                                         xmlNode *node,
diff --git a/e-util/gal-a11y-e-table-column-header.c b/e-util/gal-a11y-e-table-column-header.c
index 4fcc274..9977843 100644
--- a/e-util/gal-a11y-e-table-column-header.c
+++ b/e-util/gal-a11y-e-table-column-header.c
@@ -137,7 +137,7 @@ gal_a11y_e_table_column_header_do_action (AtkAction *action,
                                        E_TABLE (widget)->header_item);
                        else
                                break;
-                       ethi_change_sort_state (ethi, col);
+                       ethi_change_sort_state (ethi, col, E_TABLE_HEADER_ITEM_SORT_FLAG_NONE);
                default:
                        return_value = FALSE;
                        break;


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