aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2013-06-21 04:44:24 +0800
committerMatthew Barnes <mbarnes@redhat.com>2013-06-21 04:44:24 +0800
commit9f9d4803090b84a6b7c1851a716229455692992e (patch)
treebaae9c100a0d1e0335fcee37cd587a90c71e951e
parentf8a116931cf7d86bde7a8a26223cd0573e50427a (diff)
downloadgsoc2013-evolution-9f9d4803090b84a6b7c1851a716229455692992e.tar
gsoc2013-evolution-9f9d4803090b84a6b7c1851a716229455692992e.tar.gz
gsoc2013-evolution-9f9d4803090b84a6b7c1851a716229455692992e.tar.bz2
gsoc2013-evolution-9f9d4803090b84a6b7c1851a716229455692992e.tar.lz
gsoc2013-evolution-9f9d4803090b84a6b7c1851a716229455692992e.tar.xz
gsoc2013-evolution-9f9d4803090b84a6b7c1851a716229455692992e.tar.zst
gsoc2013-evolution-9f9d4803090b84a6b7c1851a716229455692992e.zip
ETableSorter: Further cleanups.
-rw-r--r--e-util/e-table-sorter.c678
-rw-r--r--e-util/e-table-sorter.h28
2 files changed, 347 insertions, 359 deletions
diff --git a/e-util/e-table-sorter.c b/e-util/e-table-sorter.c
index a74bc3626c..e570042217 100644
--- a/e-util/e-table-sorter.c
+++ b/e-util/e-table-sorter.c
@@ -1,4 +1,6 @@
/*
+ * e-table-sorter.c
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -12,12 +14,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
*/
#ifdef HAVE_CONFIG_H
@@ -39,18 +35,6 @@ enum {
PROP_SORT_INFO
};
-#define INCREMENT_AMOUNT 100
-
-static void ets_model_changed (ETableModel *etm, ETableSorter *ets);
-static void ets_model_row_changed (ETableModel *etm, gint row, ETableSorter *ets);
-static void ets_model_cell_changed (ETableModel *etm, gint col, gint row, ETableSorter *ets);
-static void ets_model_rows_inserted (ETableModel *etm, gint row, gint count, ETableSorter *ets);
-static void ets_model_rows_deleted (ETableModel *etm, gint row, gint count, ETableSorter *ets);
-static void ets_sort_info_changed (ETableSortInfo *info, ETableSorter *ets);
-static void ets_clean (ETableSorter *ets);
-static void ets_sort (ETableSorter *ets);
-static void ets_backsort (ETableSorter *ets);
-
/* Forward Declarations */
static void e_table_sorter_interface_init (ESorterInterface *interface);
@@ -62,92 +46,225 @@ G_DEFINE_TYPE_WITH_CODE (
E_TYPE_SORTER,
e_table_sorter_interface_init))
+struct qsort_data {
+ ETableSorter *table_sorter;
+ gpointer *vals;
+ gint cols;
+ gint *ascending;
+ GCompareDataFunc *compare;
+ gpointer cmp_cache;
+};
+
+/* FIXME: Make it not cache the second and later columns (as if anyone cares.) */
+
+static gint
+qsort_callback (gconstpointer data1,
+ gconstpointer data2,
+ gpointer user_data)
+{
+ struct qsort_data *qd = (struct qsort_data *) user_data;
+ gint row1 = *(gint *) data1;
+ gint row2 = *(gint *) data2;
+ gint j;
+ gint sort_count;
+ gint comp_val = 0;
+ gint ascending = 1;
+
+ sort_count =
+ e_table_sort_info_sorting_get_count (
+ qd->table_sorter->sort_info) +
+ e_table_sort_info_grouping_get_count (
+ qd->table_sorter->sort_info);
+
+ for (j = 0; j < sort_count; j++) {
+ comp_val = (*(qd->compare[j]))(qd->vals[qd->cols * row1 + j], qd->vals[qd->cols * row2 + j], qd->cmp_cache);
+ ascending = qd->ascending[j];
+ if (comp_val != 0)
+ break;
+ }
+ if (comp_val == 0) {
+ if (row1 < row2)
+ comp_val = -1;
+ if (row1 > row2)
+ comp_val = 1;
+ }
+ if (!ascending)
+ comp_val = -comp_val;
+
+ return comp_val;
+}
+
+static void
+table_sorter_clean (ETableSorter *table_sorter)
+{
+ g_free (table_sorter->sorted);
+ table_sorter->sorted = NULL;
+
+ g_free (table_sorter->backsorted);
+ table_sorter->backsorted = NULL;
+
+ table_sorter->needs_sorting = -1;
+}
+
+static void
+table_sorter_sort (ETableSorter *table_sorter)
+{
+ gint rows;
+ gint i;
+ gint j;
+ gint cols;
+ gint group_cols;
+ struct qsort_data qd;
+
+ if (table_sorter->sorted)
+ return;
+
+ rows = e_table_model_row_count (table_sorter->source);
+ group_cols = e_table_sort_info_grouping_get_count (table_sorter->sort_info);
+ cols = e_table_sort_info_sorting_get_count (table_sorter->sort_info) + group_cols;
+
+ table_sorter->sorted = g_new (int, rows);
+ for (i = 0; i < rows; i++)
+ table_sorter->sorted[i] = i;
+
+ qd.cols = cols;
+ qd.table_sorter = table_sorter;
+
+ qd.vals = g_new (gpointer , rows * cols);
+ qd.ascending = g_new (int, cols);
+ qd.compare = g_new (GCompareDataFunc, cols);
+ qd.cmp_cache = e_table_sorting_utils_create_cmp_cache ();
+
+ for (j = 0; j < cols; j++) {
+ ETableSortColumn column;
+ ETableCol *col;
+
+ if (j < group_cols)
+ column = e_table_sort_info_grouping_get_nth (table_sorter->sort_info, j);
+ 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);
+
+ for (i = 0; i < rows; i++) {
+ qd.vals[i * cols + j] = e_table_model_value_at (table_sorter->source, col->col_idx, i);
+ }
+
+ qd.compare[j] = col->compare;
+ qd.ascending[j] = column.ascending;
+ }
+
+ g_qsort_with_data (table_sorter->sorted, rows, sizeof (gint), qsort_callback, &qd);
+
+ g_free (qd.vals);
+ g_free (qd.ascending);
+ g_free (qd.compare);
+ e_table_sorting_utils_free_cmp_cache (qd.cmp_cache);
+}
+
static void
-ets_dispose (GObject *object)
+table_sorter_backsort (ETableSorter *table_sorter)
{
- ETableSorter *ets = E_TABLE_SORTER (object);
-
- if (ets->sort_info) {
- if (ets->table_model_changed_id)
- g_signal_handler_disconnect (
- ets->source,
- ets->table_model_changed_id);
- if (ets->table_model_row_changed_id)
- g_signal_handler_disconnect (
- ets->source,
- ets->table_model_row_changed_id);
- if (ets->table_model_cell_changed_id)
- g_signal_handler_disconnect (
- ets->source,
- ets->table_model_cell_changed_id);
- if (ets->table_model_rows_inserted_id)
- g_signal_handler_disconnect (
- ets->source,
- ets->table_model_rows_inserted_id);
- if (ets->table_model_rows_deleted_id)
- g_signal_handler_disconnect (
- ets->source,
- ets->table_model_rows_deleted_id);
- if (ets->sort_info_changed_id)
- g_signal_handler_disconnect (
- ets->sort_info,
- ets->sort_info_changed_id);
- if (ets->group_info_changed_id)
- g_signal_handler_disconnect (
- ets->sort_info,
- ets->group_info_changed_id);
-
- ets->table_model_changed_id = 0;
- ets->table_model_row_changed_id = 0;
- ets->table_model_cell_changed_id = 0;
- ets->table_model_rows_inserted_id = 0;
- ets->table_model_rows_deleted_id = 0;
- ets->sort_info_changed_id = 0;
- ets->group_info_changed_id = 0;
-
- g_object_unref (ets->sort_info);
- ets->sort_info = NULL;
+ gint i, rows;
+
+ if (table_sorter->backsorted)
+ return;
+
+ table_sorter_sort (table_sorter);
+
+ rows = e_table_model_row_count (table_sorter->source);
+ table_sorter->backsorted = g_new0 (int, rows);
+
+ for (i = 0; i < rows; i++) {
+ table_sorter->backsorted[table_sorter->sorted[i]] = i;
}
+}
- if (ets->full_header)
- g_object_unref (ets->full_header);
- ets->full_header = NULL;
+static void
+table_sorter_model_changed_cb (ETableModel *table_model,
+ ETableSorter *table_sorter)
+{
+ table_sorter_clean (table_sorter);
+}
- if (ets->source)
- g_object_unref (ets->source);
- ets->source = NULL;
+static void
+table_sorter_model_row_changed_cb (ETableModel *table_model,
+ gint row,
+ ETableSorter *table_sorter)
+{
+ table_sorter_clean (table_sorter);
+}
- G_OBJECT_CLASS (e_table_sorter_parent_class)->dispose (object);
+static void
+table_sorter_model_cell_changed_cb (ETableModel *table_model,
+ gint col,
+ gint row,
+ ETableSorter *table_sorter)
+{
+ table_sorter_clean (table_sorter);
+}
+
+static void
+table_sorter_model_rows_inserted_cb (ETableModel *table_model,
+ gint row,
+ gint count,
+ ETableSorter *table_sorter)
+{
+ table_sorter_clean (table_sorter);
+}
+
+static void
+table_sorter_model_rows_deleted_cb (ETableModel *table_model,
+ gint row,
+ gint count,
+ ETableSorter *table_sorter)
+{
+ table_sorter_clean (table_sorter);
+}
+
+static void
+table_sorter_sort_info_changed_cb (ETableSortInfo *sort_info,
+ ETableSorter *table_sorter)
+{
+ table_sorter_clean (table_sorter);
}
static void
-ets_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+table_sorter_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- ETableSorter *ets = E_TABLE_SORTER (object);
+ ETableSorter *table_sorter = E_TABLE_SORTER (object);
switch (property_id) {
case PROP_SORT_INFO:
- if (ets->sort_info) {
- if (ets->sort_info_changed_id)
- g_signal_handler_disconnect (ets->sort_info, ets->sort_info_changed_id);
- if (ets->group_info_changed_id)
- g_signal_handler_disconnect (ets->sort_info, ets->group_info_changed_id);
- g_object_unref (ets->sort_info);
+ if (table_sorter->sort_info) {
+ if (table_sorter->sort_info_changed_id)
+ g_signal_handler_disconnect (
+ table_sorter->sort_info,
+ table_sorter->sort_info_changed_id);
+ if (table_sorter->group_info_changed_id)
+ g_signal_handler_disconnect (
+ table_sorter->sort_info,
+ table_sorter->group_info_changed_id);
+ g_object_unref (table_sorter->sort_info);
}
- ets->sort_info = E_TABLE_SORT_INFO (g_value_get_object (value));
- g_object_ref (ets->sort_info);
- ets->sort_info_changed_id = g_signal_connect (
- ets->sort_info, "sort_info_changed",
- G_CALLBACK (ets_sort_info_changed), ets);
- ets->group_info_changed_id = g_signal_connect (
- ets->sort_info, "group_info_changed",
- G_CALLBACK (ets_sort_info_changed), ets);
+ table_sorter->sort_info = g_value_dup_object (value);
- ets_clean (ets);
+ table_sorter->sort_info_changed_id = g_signal_connect (
+ table_sorter->sort_info, "sort_info_changed",
+ G_CALLBACK (table_sorter_sort_info_changed_cb),
+ table_sorter);
+ table_sorter->group_info_changed_id = g_signal_connect (
+ table_sorter->sort_info, "group_info_changed",
+ G_CALLBACK (table_sorter_sort_info_changed_cb),
+ table_sorter);
+
+ table_sorter_clean (table_sorter);
break;
default:
break;
@@ -155,109 +272,176 @@ ets_set_property (GObject *object,
}
static void
-ets_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
+table_sorter_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- ETableSorter *ets = E_TABLE_SORTER (object);
+ ETableSorter *table_sorter = E_TABLE_SORTER (object);
switch (property_id) {
case PROP_SORT_INFO:
- g_value_set_object (value, ets->sort_info);
+ g_value_set_object (value, table_sorter->sort_info);
break;
}
}
+static void
+table_sorter_dispose (GObject *object)
+{
+ ETableSorter *table_sorter = E_TABLE_SORTER (object);
+
+ if (table_sorter->table_model_changed_id > 0) {
+ g_signal_handler_disconnect (
+ table_sorter->source,
+ table_sorter->table_model_changed_id);
+ table_sorter->table_model_changed_id = 0;
+ }
+
+ if (table_sorter->table_model_row_changed_id > 0) {
+ g_signal_handler_disconnect (
+ table_sorter->source,
+ table_sorter->table_model_row_changed_id);
+ table_sorter->table_model_row_changed_id = 0;
+ }
+
+ if (table_sorter->table_model_cell_changed_id > 0) {
+ g_signal_handler_disconnect (
+ table_sorter->source,
+ table_sorter->table_model_cell_changed_id);
+ table_sorter->table_model_cell_changed_id = 0;
+ }
+
+ if (table_sorter->table_model_rows_inserted_id > 0) {
+ g_signal_handler_disconnect (
+ table_sorter->source,
+ table_sorter->table_model_rows_inserted_id);
+ table_sorter->table_model_rows_inserted_id = 0;
+ }
+
+ if (table_sorter->table_model_rows_deleted_id > 0) {
+ g_signal_handler_disconnect (
+ table_sorter->source,
+ table_sorter->table_model_rows_deleted_id);
+ table_sorter->table_model_rows_deleted_id = 0;
+ }
+
+ if (table_sorter->sort_info_changed_id > 0) {
+ g_signal_handler_disconnect (
+ table_sorter->sort_info,
+ table_sorter->sort_info_changed_id);
+ table_sorter->sort_info_changed_id = 0;
+ }
+
+ if (table_sorter->group_info_changed_id > 0) {
+ g_signal_handler_disconnect (
+ table_sorter->sort_info,
+ table_sorter->group_info_changed_id);
+ table_sorter->group_info_changed_id = 0;
+ }
+
+ g_clear_object (&table_sorter->sort_info);
+ g_clear_object (&table_sorter->full_header);
+ g_clear_object (&table_sorter->source);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_table_sorter_parent_class)->dispose (object);
+}
+
static gint
-table_sorter_model_to_sorted (ESorter *es,
+table_sorter_model_to_sorted (ESorter *sorter,
gint row)
{
- ETableSorter *ets = E_TABLE_SORTER (es);
- gint rows = e_table_model_row_count (ets->source);
+ ETableSorter *table_sorter = E_TABLE_SORTER (sorter);
+ gint rows = e_table_model_row_count (table_sorter->source);
g_return_val_if_fail (row >= 0, -1);
g_return_val_if_fail (row < rows, -1);
- if (e_sorter_needs_sorting (es))
- ets_backsort (ets);
+ if (e_sorter_needs_sorting (sorter))
+ table_sorter_backsort (table_sorter);
- if (ets->backsorted)
- return ets->backsorted[row];
+ if (table_sorter->backsorted)
+ return table_sorter->backsorted[row];
else
return row;
}
static gint
-table_sorter_sorted_to_model (ESorter *es,
+table_sorter_sorted_to_model (ESorter *sorter,
gint row)
{
- ETableSorter *ets = E_TABLE_SORTER (es);
- gint rows = e_table_model_row_count (ets->source);
+ ETableSorter *table_sorter = E_TABLE_SORTER (sorter);
+ gint rows = e_table_model_row_count (table_sorter->source);
g_return_val_if_fail (row >= 0, -1);
g_return_val_if_fail (row < rows, -1);
- if (e_sorter_needs_sorting (es))
- ets_sort (ets);
+ if (e_sorter_needs_sorting (sorter))
+ table_sorter_sort (table_sorter);
- if (ets->sorted)
- return ets->sorted[row];
+ if (table_sorter->sorted)
+ return table_sorter->sorted[row];
else
return row;
}
static void
-table_sorter_get_model_to_sorted_array (ESorter *es,
+table_sorter_get_model_to_sorted_array (ESorter *sorter,
gint **array,
gint *count)
{
- ETableSorter *ets = E_TABLE_SORTER (es);
+ ETableSorter *table_sorter = E_TABLE_SORTER (sorter);
+
if (array || count) {
- ets_backsort (ets);
+ table_sorter_backsort (table_sorter);
if (array)
- *array = ets->backsorted;
+ *array = table_sorter->backsorted;
if (count)
- *count = e_table_model_row_count(ets->source);
+ *count = e_table_model_row_count(table_sorter->source);
}
}
static void
-table_sorter_get_sorted_to_model_array (ESorter *es,
+table_sorter_get_sorted_to_model_array (ESorter *sorter,
gint **array,
gint *count)
{
- ETableSorter *ets = E_TABLE_SORTER (es);
+ ETableSorter *table_sorter = E_TABLE_SORTER (sorter);
+
if (array || count) {
- ets_sort (ets);
+ table_sorter_sort (table_sorter);
if (array)
- *array = ets->sorted;
+ *array = table_sorter->sorted;
if (count)
- *count = e_table_model_row_count(ets->source);
+ *count = e_table_model_row_count(table_sorter->source);
}
}
static gboolean
-table_sorter_needs_sorting (ESorter *es)
+table_sorter_needs_sorting (ESorter *sorter)
{
- ETableSorter *ets = E_TABLE_SORTER (es);
- if (ets->needs_sorting < 0) {
- if (e_table_sort_info_sorting_get_count (ets->sort_info) + e_table_sort_info_grouping_get_count (ets->sort_info))
- ets->needs_sorting = 1;
+ ETableSorter *table_sorter = E_TABLE_SORTER (sorter);
+
+ if (table_sorter->needs_sorting < 0) {
+ if (e_table_sort_info_sorting_get_count (table_sorter->sort_info) + e_table_sort_info_grouping_get_count (table_sorter->sort_info))
+ table_sorter->needs_sorting = 1;
else
- ets->needs_sorting = 0;
+ table_sorter->needs_sorting = 0;
}
- return ets->needs_sorting;
+ return table_sorter->needs_sorting;
}
+
static void
e_table_sorter_class_init (ETableSorterClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GObjectClass *object_class;
- object_class->dispose = ets_dispose;
- object_class->set_property = ets_set_property;
- object_class->get_property = ets_get_property;
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = table_sorter_set_property;
+ object_class->get_property = table_sorter_get_property;
+ object_class->dispose = table_sorter_dispose;
g_object_class_install_property (
object_class,
@@ -281,21 +465,9 @@ e_table_sorter_interface_init (ESorterInterface *interface)
}
static void
-e_table_sorter_init (ETableSorter *ets)
+e_table_sorter_init (ETableSorter *table_sorter)
{
- ets->full_header = NULL;
- ets->sort_info = NULL;
- ets->source = NULL;
-
- ets->needs_sorting = -1;
-
- ets->table_model_changed_id = 0;
- ets->table_model_row_changed_id = 0;
- ets->table_model_cell_changed_id = 0;
- ets->table_model_rows_inserted_id = 0;
- ets->table_model_rows_deleted_id = 0;
- ets->sort_info_changed_id = 0;
- ets->group_info_changed_id = 0;
+ table_sorter->needs_sorting = -1;
}
ETableSorter *
@@ -303,221 +475,41 @@ e_table_sorter_new (ETableModel *source,
ETableHeader *full_header,
ETableSortInfo *sort_info)
{
- ETableSorter *ets = g_object_new (E_TYPE_TABLE_SORTER, NULL);
+ ETableSorter *table_sorter;
- ets->sort_info = sort_info;
- g_object_ref (ets->sort_info);
- ets->full_header = full_header;
- g_object_ref (ets->full_header);
- ets->source = source;
- g_object_ref (ets->source);
+ table_sorter = g_object_new (E_TYPE_TABLE_SORTER, NULL);
+ table_sorter->sort_info = g_object_ref (sort_info);
+ table_sorter->full_header = g_object_ref (full_header);
+ table_sorter->source = g_object_ref (source);
- ets->table_model_changed_id = g_signal_connect (
+ table_sorter->table_model_changed_id = g_signal_connect (
source, "model_changed",
- G_CALLBACK (ets_model_changed), ets);
+ G_CALLBACK (table_sorter_model_changed_cb), table_sorter);
- ets->table_model_row_changed_id = g_signal_connect (
+ table_sorter->table_model_row_changed_id = g_signal_connect (
source, "model_row_changed",
- G_CALLBACK (ets_model_row_changed), ets);
+ G_CALLBACK (table_sorter_model_row_changed_cb), table_sorter);
- ets->table_model_cell_changed_id = g_signal_connect (
+ table_sorter->table_model_cell_changed_id = g_signal_connect (
source, "model_cell_changed",
- G_CALLBACK (ets_model_cell_changed), ets);
+ G_CALLBACK (table_sorter_model_cell_changed_cb), table_sorter);
- ets->table_model_rows_inserted_id = g_signal_connect (
+ table_sorter->table_model_rows_inserted_id = g_signal_connect (
source, "model_rows_inserted",
- G_CALLBACK (ets_model_rows_inserted), ets);
+ G_CALLBACK (table_sorter_model_rows_inserted_cb), table_sorter);
- ets->table_model_rows_deleted_id = g_signal_connect (
+ table_sorter->table_model_rows_deleted_id = g_signal_connect (
source, "model_rows_deleted",
- G_CALLBACK (ets_model_rows_deleted), ets);
+ G_CALLBACK (table_sorter_model_rows_deleted_cb), table_sorter);
- ets->sort_info_changed_id = g_signal_connect (
+ table_sorter->sort_info_changed_id = g_signal_connect (
sort_info, "sort_info_changed",
- G_CALLBACK (ets_sort_info_changed), ets);
+ G_CALLBACK (table_sorter_sort_info_changed_cb), table_sorter);
- ets->group_info_changed_id = g_signal_connect (
+ table_sorter->group_info_changed_id = g_signal_connect (
sort_info, "group_info_changed",
- G_CALLBACK (ets_sort_info_changed), ets);
-
- return ets;
-}
-
-static void
-ets_model_changed (ETableModel *etm,
- ETableSorter *ets)
-{
- ets_clean (ets);
-}
-
-static void
-ets_model_row_changed (ETableModel *etm,
- gint row,
- ETableSorter *ets)
-{
- ets_clean (ets);
-}
-
-static void
-ets_model_cell_changed (ETableModel *etm,
- gint col,
- gint row,
- ETableSorter *ets)
-{
- ets_clean (ets);
-}
-
-static void
-ets_model_rows_inserted (ETableModel *etm,
- gint row,
- gint count,
- ETableSorter *ets)
-{
- ets_clean (ets);
-}
-
-static void
-ets_model_rows_deleted (ETableModel *etm,
- gint row,
- gint count,
- ETableSorter *ets)
-{
- ets_clean (ets);
-}
-
-static void
-ets_sort_info_changed (ETableSortInfo *info,
- ETableSorter *ets)
-{
- d (g_print ("sort info changed\n"));
- ets_clean (ets);
-}
-
-struct qsort_data {
- ETableSorter *ets;
- gpointer *vals;
- gint cols;
- gint *ascending;
- GCompareDataFunc *compare;
- gpointer cmp_cache;
-};
-
-/* FIXME: Make it not cache the second and later columns (as if anyone cares.) */
-
-static gint
-qsort_callback (gconstpointer data1,
- gconstpointer data2,
- gpointer user_data)
-{
- struct qsort_data *qd = (struct qsort_data *) user_data;
- gint row1 = *(gint *) data1;
- gint row2 = *(gint *) data2;
- gint j;
- gint sort_count = e_table_sort_info_sorting_get_count (qd->ets->sort_info) + e_table_sort_info_grouping_get_count (qd->ets->sort_info);
- gint comp_val = 0;
- gint ascending = 1;
- for (j = 0; j < sort_count; j++) {
- comp_val = (*(qd->compare[j]))(qd->vals[qd->cols * row1 + j], qd->vals[qd->cols * row2 + j], qd->cmp_cache);
- ascending = qd->ascending[j];
- if (comp_val != 0)
- break;
- }
- if (comp_val == 0) {
- if (row1 < row2)
- comp_val = -1;
- if (row1 > row2)
- comp_val = 1;
- }
- if (!ascending)
- comp_val = -comp_val;
- return comp_val;
-}
+ G_CALLBACK (table_sorter_sort_info_changed_cb), table_sorter);
-static void
-ets_clean (ETableSorter *ets)
-{
- g_free (ets->sorted);
- ets->sorted = NULL;
-
- g_free (ets->backsorted);
- ets->backsorted = NULL;
-
- ets->needs_sorting = -1;
-}
-
-static void
-ets_sort (ETableSorter *ets)
-{
- gint rows;
- gint i;
- gint j;
- gint cols;
- gint group_cols;
- struct qsort_data qd;
-
- if (ets->sorted)
- return;
-
- rows = e_table_model_row_count (ets->source);
- group_cols = e_table_sort_info_grouping_get_count (ets->sort_info);
- cols = e_table_sort_info_sorting_get_count (ets->sort_info) + group_cols;
-
- ets->sorted = g_new (int, rows);
- for (i = 0; i < rows; i++)
- ets->sorted[i] = i;
-
- qd.cols = cols;
- qd.ets = ets;
-
- qd.vals = g_new (gpointer , rows * cols);
- qd.ascending = g_new (int, cols);
- qd.compare = g_new (GCompareDataFunc, cols);
- qd.cmp_cache = e_table_sorting_utils_create_cmp_cache ();
-
- for (j = 0; j < cols; j++) {
- ETableSortColumn column;
- ETableCol *col;
-
- if (j < group_cols)
- column = e_table_sort_info_grouping_get_nth (ets->sort_info, j);
- else
- column = e_table_sort_info_sorting_get_nth (ets->sort_info, j - group_cols);
-
- col = e_table_header_get_column_by_col_idx (ets->full_header, column.column);
- if (col == NULL)
- col = e_table_header_get_column (ets->full_header, e_table_header_count (ets->full_header) - 1);
-
- for (i = 0; i < rows; i++) {
- qd.vals[i * cols + j] = e_table_model_value_at (ets->source, col->col_idx, i);
- }
-
- qd.compare[j] = col->compare;
- qd.ascending[j] = column.ascending;
- }
-
- g_qsort_with_data (ets->sorted, rows, sizeof (gint), qsort_callback, &qd);
-
- g_free (qd.vals);
- g_free (qd.ascending);
- g_free (qd.compare);
- e_table_sorting_utils_free_cmp_cache (qd.cmp_cache);
-}
-
-static void
-ets_backsort (ETableSorter *ets)
-{
- gint i, rows;
-
- if (ets->backsorted)
- return;
-
- ets_sort (ets);
-
- rows = e_table_model_row_count (ets->source);
- ets->backsorted = g_new0 (int, rows);
-
- for (i = 0; i < rows; i++) {
- ets->backsorted[ets->sorted[i]] = i;
- }
+ return table_sorter;
}
diff --git a/e-util/e-table-sorter.h b/e-util/e-table-sorter.h
index a32116edf7..7dbba44311 100644
--- a/e-util/e-table-sorter.h
+++ b/e-util/e-table-sorter.h
@@ -1,4 +1,6 @@
/*
+ * e-table-sorter.h
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -12,20 +14,14 @@
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
*/
#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
#error "Only <e-util/e-util.h> should be included directly."
#endif
-#ifndef _E_TABLE_SORTER_H_
-#define _E_TABLE_SORTER_H_
+#ifndef E_TABLE_SORTER_H
+#define E_TABLE_SORTER_H
#include <e-util/e-sorter.h>
#include <e-util/e-table-header.h>
@@ -71,13 +67,13 @@ struct _ETableSorter {
gint *sorted;
gint *backsorted;
- gint table_model_changed_id;
- gint table_model_row_changed_id;
- gint table_model_cell_changed_id;
- gint table_model_rows_inserted_id;
- gint table_model_rows_deleted_id;
- gint sort_info_changed_id;
- gint group_info_changed_id;
+ gulong table_model_changed_id;
+ gulong table_model_row_changed_id;
+ gulong table_model_cell_changed_id;
+ gulong table_model_rows_inserted_id;
+ gulong table_model_rows_deleted_id;
+ gulong sort_info_changed_id;
+ gulong group_info_changed_id;
};
struct _ETableSorterClass {
@@ -91,4 +87,4 @@ ETableSorter * e_table_sorter_new (ETableModel *etm,
G_END_DECLS
-#endif /* _E_TABLE_SORTER_H_ */
+#endif /* E_TABLE_SORTER_H */