gboolean e_table_sorting_utils_affects_sort (ETableSortInfo *sort_info, ETableHeader *full_header, gint compare_col) { gint j; gint cols; g_return_val_if_fail (E_IS_TABLE_SORT_INFO (sort_info), TRUE); g_return_val_if_fail (E_IS_TABLE_HEADER (full_header), TRUE); cols = e_table_sort_info_sorting_get_count (sort_info); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; 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); } if (compare_col == col->spec->compare_col) return TRUE; } return FALSE; }
static void sort_ascending_toggled (GtkToggleButton *t, ETableConfigSortWidgets *sort) { ETableConfig *config = sort->e_table_config; ETableSortInfo *si = config->temp_state->sort_info; ETableConfigSortWidgets *base = &config->sort[0]; int idx = sort - base; ETableSortColumn c; c = e_table_sort_info_sorting_get_nth (si, idx); c.ascending = t->active; e_table_sort_info_sorting_set_nth (si, idx, c); }
/* This takes source rows. */ static gint etsu_compare (ETableModel *source, ETableSortInfo *sort_info, ETableHeader *full_header, gint row1, gint row2, gpointer cmp_cache) { gint j; gint sort_count = e_table_sort_info_sorting_get_count (sort_info); gint comp_val = 0; GtkSortType sort_type = GTK_SORT_ASCENDING; for (j = 0; j < sort_count; j++) { ETableColumnSpecification *spec; ETableCol *col; gpointer value1, value2; 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); } value1 = e_table_model_value_at (source, col->spec->compare_col, row1); value2 = e_table_model_value_at (source, col->spec->compare_col, row2); comp_val = (*col->compare) (value1, value2, cmp_cache); e_table_model_free_value (source, col->spec->compare_col, value1); e_table_model_free_value (source, col->spec->compare_col, value2); if (comp_val != 0) break; } if (comp_val == 0) { if (row1 < row2) comp_val = -1; if (row1 > row2) comp_val = 1; } if (sort_type == GTK_SORT_DESCENDING) comp_val = -comp_val; return comp_val; }
ETableCol * e_table_util_calculate_current_search_col (ETableHeader *header, ETableHeader *full_header, ETableSortInfo *sort_info, gboolean always_search) { gint i; gint count; ETableCol *col = NULL; count = e_table_sort_info_grouping_get_count (sort_info); for (i = 0; i < count; i++) { ETableSortColumn column = e_table_sort_info_grouping_get_nth (sort_info, i); col = e_table_header_get_column (full_header, column.column); if (col && col->search) break; col = NULL; } if (col == NULL) { count = e_table_sort_info_sorting_get_count (sort_info); for (i = 0; i < count; i++) { ETableSortColumn column = e_table_sort_info_sorting_get_nth (sort_info, i); col = e_table_header_get_column (full_header, column.column); if (col && col->search) break; col = NULL; } } if (col == NULL && always_search) { col = e_table_header_prioritized_column_selected (header, check_col, NULL); } return col; }
/* This takes source rows. */ static gint etsu_tree_compare (ETreeModel *source, ETableSortInfo *sort_info, ETableHeader *full_header, ETreePath path1, ETreePath path2, gpointer cmp_cache) { gint j; gint sort_count = e_table_sort_info_sorting_get_count (sort_info); gint comp_val = 0; GtkSortType sort_type = GTK_SORT_ASCENDING; for (j = 0; j < sort_count; j++) { ETableColumnSpecification *spec; ETableCol *col; 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); } comp_val = (*col->compare) ( e_tree_model_value_at ( source, path1, col->spec->compare_col), e_tree_model_value_at ( source, path2, col->spec->compare_col), cmp_cache); if (comp_val != 0) break; } if (sort_type == GTK_SORT_DESCENDING) comp_val = -comp_val; return comp_val; }
static void config_sort_info_update (ETableConfig *config) { ETableSortInfo *info = config->state->sort_info; GString *res; int count, i; count = e_table_sort_info_sorting_get_count (info); res = g_string_new (""); for (i = 0; i < count; i++) { ETableSortColumn col = e_table_sort_info_sorting_get_nth (info, i); ETableColumnSpecification *column; column = find_column_in_spec (config->source_spec, col.column); if (!column){ g_warning ("Could not find column model in specification"); continue; } g_string_append (res, dgettext (config->domain, (column)->title)); g_string_append_c (res, ' '); g_string_append ( res, col.ascending ? _("(Ascending)") : _("(Descending)")); if ((i + 1) != count) g_string_append (res, ", "); } if (res->str [0] == 0) g_string_append (res, _("Not sorted")); gtk_label_set_text (GTK_LABEL(config->sort_label), res->str); g_string_free (res, TRUE); }
static void update_sort_and_group_config_dialog (ETableConfig *config, gboolean is_sort) { ETableConfigSortWidgets *widgets; int count, i; if (is_sort){ count = e_table_sort_info_sorting_get_count ( config->temp_state->sort_info); widgets = &config->sort [0]; } else { count = e_table_sort_info_grouping_get_count ( config->temp_state->sort_info); widgets = &config->group [0]; } for (i = 0; i < 4; i++){ gboolean sensitive = (i <= count); char *text = ""; gtk_widget_set_sensitive (widgets [i].frames, sensitive); /* * Sorting is set, auto select the text */ g_signal_handler_block ( widgets [i].radio_ascending, widgets [i].toggled_id); g_signal_handler_block ( widgets [i].combo, 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){ /* * This is a bug in the programmer * stuff, but by the time we arrive * here, the user has been given a * warning */ continue; } text = column->title; /* * 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); } else { GtkToggleButton *t; t = GTK_TOGGLE_BUTTON ( widgets [i].radio_ascending); if (is_sort) g_return_if_fail (widgets [i].radio_ascending != config->group [i].radio_ascending); else g_return_if_fail (widgets [i].radio_ascending != config->sort [i].radio_ascending); gtk_toggle_button_set_active (t, 1); } /* Set the text */ configure_combo_box_set_active ( GTK_COMBO_BOX (widgets[i].combo), text); g_signal_handler_unblock ( widgets [i].radio_ascending, widgets [i].toggled_id); g_signal_handler_unblock ( widgets [i].combo, widgets [i].changed_id); } }
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++) { ETableColumnSpecification *spec; ETableCol *col; GtkSortType sort_type; if (j < group_cols) spec = e_table_sort_info_grouping_get_nth ( table_sorter->sort_info, j, &sort_type); else 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.compare[j] = col->compare; qd.ascending[j] = (sort_type == GTK_SORT_ASCENDING); } g_qsort_with_data (table_sorter->sorted, rows, sizeof (gint), qsort_callback, &qd); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; GtkSortType sort_type; if (j < group_cols) spec = e_table_sort_info_grouping_get_nth ( table_sorter->sort_info, j, &sort_type); else 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++) { e_table_model_free_value (table_sorter->source, col->spec->model_col, qd.vals[i * cols + j]); } } g_free (qd.vals); g_free (qd.ascending); g_free (qd.compare); e_table_sorting_utils_free_cmp_cache (qd.cmp_cache); }
void e_table_sorting_utils_tree_sort (ETreeModel *source, ETableSortInfo *sort_info, ETableHeader *full_header, ETreePath *map_table, gint count) { ETableSortClosure closure; gint cols; gint i, j; gint *map; ETreePath *map_copy; g_return_if_fail (E_IS_TREE_MODEL (source)); g_return_if_fail (E_IS_TABLE_SORT_INFO (sort_info)); g_return_if_fail (E_IS_TABLE_HEADER (full_header)); cols = e_table_sort_info_sorting_get_count (sort_info); closure.cols = cols; closure.vals = g_new (gpointer , count * cols); closure.sort_type = g_new (GtkSortType, cols); closure.compare = g_new (GCompareDataFunc, cols); closure.cmp_cache = e_table_sorting_utils_create_cmp_cache (); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; 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); } for (i = 0; i < count; i++) { closure.vals[i * cols + j] = e_tree_model_sort_value_at (source, map_table[i], col->spec->compare_col); } closure.compare[j] = col->compare; } map = g_new (int, count); for (i = 0; i < count; i++) { map[i] = i; } g_qsort_with_data ( map, count, sizeof (gint), e_sort_callback, &closure); map_copy = g_new (ETreePath, count); for (i = 0; i < count; i++) { map_copy[i] = map_table[i]; } for (i = 0; i < count; i++) { map_table[i] = map_copy[map[i]]; } for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; 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); } for (i = 0; i < count; i++) { e_tree_model_free_value (source, col->spec->compare_col, closure.vals[i * cols + j]); } } g_free (map); g_free (map_copy); g_free (closure.vals); g_free (closure.sort_type); g_free (closure.compare); e_table_sorting_utils_free_cmp_cache (closure.cmp_cache); }
void e_table_sorting_utils_sort (ETableModel *source, ETableSortInfo *sort_info, ETableHeader *full_header, gint *map_table, gint rows) { gint total_rows; gint i; gint j; gint cols; ETableSortClosure closure; g_return_if_fail (E_IS_TABLE_MODEL (source)); g_return_if_fail (E_IS_TABLE_SORT_INFO (sort_info)); g_return_if_fail (E_IS_TABLE_HEADER (full_header)); total_rows = e_table_model_row_count (source); cols = e_table_sort_info_sorting_get_count (sort_info); closure.cols = cols; closure.vals = g_new (gpointer, total_rows * cols); closure.sort_type = g_new (GtkSortType, cols); closure.compare = g_new (GCompareDataFunc, cols); closure.cmp_cache = e_table_sorting_utils_create_cmp_cache (); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; 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); } for (i = 0; i < rows; i++) { 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; } g_qsort_with_data ( map_table, rows, sizeof (gint), e_sort_callback, &closure); for (j = 0; j < cols; j++) { ETableColumnSpecification *spec; ETableCol *col; 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); } for (i = 0; i < rows; i++) { e_table_model_free_value (source, col->spec->compare_col, closure.vals[map_table[i] * cols + j]); } } g_free (closure.vals); g_free (closure.sort_type); g_free (closure.compare); e_table_sorting_utils_free_cmp_cache (closure.cmp_cache); }