aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table/e-table-sorting-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/table/e-table-sorting-utils.c')
-rw-r--r--widgets/table/e-table-sorting-utils.c168
1 files changed, 162 insertions, 6 deletions
diff --git a/widgets/table/e-table-sorting-utils.c b/widgets/table/e-table-sorting-utils.c
index c5f58b8795..364397d17f 100644
--- a/widgets/table/e-table-sorting-utils.c
+++ b/widgets/table/e-table-sorting-utils.c
@@ -5,6 +5,38 @@
#define d(x)
+/* This takes source rows. */
+static int
+etsu_compare(ETableModel *source, ETableSortInfo *sort_info, ETableHeader *full_header, int row1, int row2)
+{
+ int j;
+ int sort_count = e_table_sort_info_sorting_get_count(sort_info);
+ int comp_val = 0;
+ int ascending = 1;
+
+ for (j = 0; j < sort_count; j++) {
+ ETableSortColumn column = e_table_sort_info_sorting_get_nth(sort_info, j);
+ ETableCol *col;
+ col = e_table_header_get_column_by_col_idx(full_header, column.column);
+ if (col == NULL)
+ col = e_table_header_get_column (full_header, e_table_header_count (full_header) - 1);
+ comp_val = (*col->compare)(e_table_model_value_at (source, col->col_idx, row1),
+ e_table_model_value_at (source, col->col_idx, row2));
+ ascending = column.ascending;
+ 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 ETableSortInfo *sort_info_closure;
static void **vals_closure;
@@ -319,12 +351,6 @@ e_table_sorting_utils_sort(ETableModel *source, ETableSortInfo *sort_info, ETabl
if (col == NULL)
col = e_table_header_get_column (full_header, e_table_header_count (full_header) - 1);
for (i = 0; i < rows; i++) {
-#if 0
- if( !(i & 0xff) ) {
- while(gtk_events_pending())
- gtk_main_iteration();
- }
-#endif
vals_closure[map_table[i] * cols + j] = e_table_model_value_at (source, col->col_idx, map_table[i]);
}
compare_closure[j] = col->compare;
@@ -370,3 +396,133 @@ e_table_sorting_utils_affects_sort (ETableModel *source,
}
return FALSE;
}
+
+
+int
+e_table_sorting_utils_insert(ETableModel *source, ETableSortInfo *sort_info, ETableHeader *full_header, int *map_table, int rows, int row)
+{
+ int i;
+
+ i = 0;
+ /* handle insertions when we have a 'sort group' */
+ if (e_table_model_has_sort_group(source)) {
+ /* find the row this row maps to */
+ char *group = g_strdup(e_table_model_row_sort_group(source, row));
+ const char *newgroup;
+ int cmp, grouplen, newgrouplen;
+
+ newgroup = strrchr(group, '/');
+ grouplen = strlen(group);
+ if (newgroup)
+ cmp = newgroup-group;
+ else
+ cmp = grouplen;
+
+ /* find first common parent */
+ while (i < rows) {
+ newgroup = e_table_model_row_sort_group(source, map_table[i]);
+ if (strncmp(newgroup, group, cmp) == 0) {
+ break;
+ }
+ i++;
+ }
+
+ /* check matching records */
+ while (i<row) {
+ newgroup = e_table_model_row_sort_group(source, map_table[i]);
+ newgrouplen = strlen(newgroup);
+ if (strncmp(newgroup, group, cmp) == 0) {
+ /* common parent, check for same level */
+ if (grouplen == newgrouplen) {
+ if (etsu_compare(source, sort_info, full_header, map_table[i], row) >= 0)
+ break;
+ } else if (strncmp(newgroup + cmp, group + cmp, grouplen - cmp) == 0)
+ /* Found a child of the inserted node. Insert here. */
+ break;
+ } else {
+ /* ran out of common parents, insert here */
+ break;
+ }
+ i++;
+ }
+ g_free(group);
+ } else {
+ while (i < rows && etsu_compare(source, sort_info, full_header, map_table[i], row) < 0)
+ i++;
+ }
+
+ return i;
+}
+
+#if 0
+void *bsearch(const void *key, const void *base, size_t nmemb,
+ size_t size, int (*compar)(const void *, const void *, void *), gpointer user_data)
+{
+
+}
+
+int
+e_table_sorting_utils_check_position (ETableModel *source, ETableSortInfo *sort_info, ETableHeader *full_header, int *map_table, int rows, int view_row)
+{
+ int i;
+ int row;
+
+ i = view_row;
+ row = map_table[i];
+ /* handle insertions when we have a 'sort group' */
+ if (e_table_model_has_sort_group(source)) {
+ /* find the row this row maps to */
+ char *group = g_strdup(e_table_model_row_sort_group(source, row));
+ const char *newgroup;
+ int cmp, grouplen, newgrouplen;
+
+ newgroup = strrchr(group, '/');
+ grouplen = strlen(group);
+ if (newgroup)
+ cmp = newgroup-group;
+ else
+ cmp = grouplen;
+
+ /* find first common parent */
+ while (i < rows) {
+ newgroup = e_table_model_row_sort_group(source, map_table[i]);
+ if (strncmp(newgroup, group, cmp) == 0) {
+ break;
+ }
+ i++;
+ }
+
+ /* check matching records */
+ while (i < row) {
+ newgroup = e_table_model_row_sort_group(source, map_table[i]);
+ newgrouplen = strlen(newgroup);
+ if (strncmp(newgroup, group, cmp) == 0) {
+ /* common parent, check for same level */
+ if (grouplen == newgrouplen) {
+ if (etsu_compare(source, sort_info, full_header, map_table[i], row) >= 0)
+ break;
+ } else if (strncmp(newgroup + cmp, group + cmp, grouplen - cmp) == 0)
+ /* Found a child of the inserted node. Insert here. */
+ break;
+ } else {
+ /* ran out of common parents, insert here */
+ break;
+ }
+ i++;
+ }
+ g_free(group);
+ } else {
+ i = view_row;
+ if (i < rows && etsu_compare(source, sort_info, full_header, map_table[i + 1], row) < 0) {
+ i ++;
+ while (i < rows - 1 && etsu_compare(source, sort_info, full_header, map_table[i], row) < 0)
+ i ++;
+ } else if (i > 0 && etsu_compare(source, sort_info, full_header, map_table[i - 1], row) > 0) {
+ i --;
+ while (i > 0 && etsu_compare(source, sort_info, full_header, map_table[i], row) > 0)
+ i --;
+ }
+ }
+ return i;
+}
+#endif