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 etfci_start_drag (ETableFieldChooserItem *etfci, GdkEvent *event, gdouble x, gdouble y) { GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas); GtkTargetList *list; GdkDragContext *context; ETableCol *ecol; cairo_surface_t *cs; cairo_t *cr; gint drag_col; gint button_height; GtkTargetEntry etfci_drag_types[] = { { (gchar *) TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER }, }; if (etfci->combined_header == NULL) return; drag_col = etfci_find_button (etfci, y); if (drag_col < 0 || drag_col > e_table_header_count (etfci->combined_header)) return; ecol = e_table_header_get_column (etfci->combined_header, drag_col); if (ecol->spec->disabled) return; etfci->drag_col = ecol->spec->model_col; etfci_drag_types[0].target = g_strdup_printf ( "%s-%s", etfci_drag_types[0].target, etfci->dnd_code); d (g_print ("etfci - %s\n", etfci_drag_types[0].target)); list = gtk_target_list_new (etfci_drag_types, G_N_ELEMENTS (etfci_drag_types)); context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event); g_free ((gpointer) etfci_drag_types[0].target); button_height = e_table_header_compute_height (ecol, widget); cs = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, etfci->width, button_height); cr = cairo_create (cs); e_table_header_draw_button ( cr, ecol, widget, 0, 0, etfci->width, button_height, etfci->width, button_height, E_TABLE_COL_ARROW_NONE); gtk_drag_set_icon_surface (context, cs); cairo_surface_destroy (cs); cairo_destroy (cr); etfci->maybe_drag = FALSE; }
/** * e_table_group_container_construct * @parent: The %GnomeCanvasGroup to create a child of. * @etgc: The %ETableGroupContainer. * @full_header: The full header of the %ETable. * @header: The current header of the %ETable. * @model: The %ETableModel of the %ETable. * @sort_info: The %ETableSortInfo of the %ETable. * @n: Which grouping level this is (Starts at 0 and sends n + 1 to any child %ETableGroups. * * This routine constructs the new %ETableGroupContainer. */ void e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc, ETableHeader *full_header, ETableHeader *header, ETableModel *model, ETableSortInfo *sort_info, int n) { ETableCol *col; ETableSortColumn column = e_table_sort_info_grouping_get_nth(sort_info, n); GtkStyle *style; 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); e_table_group_construct (parent, E_TABLE_GROUP (etgc), full_header, header, model); etgc->ecol = col; g_object_ref (etgc->ecol); etgc->sort_info = sort_info; g_object_ref (etgc->sort_info); etgc->n = n; etgc->ascending = column.ascending; style = GTK_WIDGET (GNOME_CANVAS_ITEM (etgc)->canvas)->style; etgc->font_desc = pango_font_description_copy (style->font_desc); etgc->open = TRUE; }
static void etfci_reflow (GnomeCanvasItem *item, gint flags) { ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item); gdouble old_height; gint i; gint count; gdouble height = 0; etfci_rebuild_combined (etfci); old_height = etfci->height; count = e_table_header_count (etfci->combined_header); for (i = 0; i < count; i++) { ETableCol *ecol; ecol = e_table_header_get_column (etfci->combined_header, i); if (ecol->spec->disabled) continue; height += e_table_header_compute_height ( ecol, GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas)); } etfci->height = height; if (old_height != etfci->height) e_canvas_item_request_parent_reflow (item); gnome_canvas_item_request_update (item); }
inline static gint view_to_model_col (ETableItem *eti, gint col) { ETableCol *ecol = e_table_header_get_column (eti->header, col); return ecol ? ecol->col_idx : -1; }
static AtkObject * eti_ref_child (AtkObject *accessible, gint index) { ETableItem *item; gint col, row; g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (accessible), NULL); item = E_TABLE_ITEM (eti_a11y_get_gobject (accessible)); if (!item) return NULL; if (index < item->cols) { ETableCol *ecol; AtkObject *child; ecol = e_table_header_get_column (item->header, index); child = gal_a11y_e_table_column_header_new (ecol, item, accessible); return child; } index -= item->cols; col = index % item->cols; row = index / item->cols; return eti_ref_at (ATK_TABLE (accessible), row, col); }
inline static gint view_to_model_col (ETableItem *eti, gint view_col) { ETableCol *ecol = e_table_header_get_column (eti->header, view_col); return (ecol != NULL) ? ecol->spec->model_col : -1; }
static void etfci_rebuild_combined (ETableFieldChooserItem *etfci) { gint count; GHashTable *hash; gint i; if (etfci->combined_header != NULL) g_object_unref (etfci->combined_header); etfci->combined_header = e_table_header_new (); hash = g_hash_table_new (NULL, NULL); count = e_table_header_count (etfci->header); for (i = 0; i < count; i++) { ETableCol *ecol = e_table_header_get_column (etfci->header, i); if (ecol->spec->disabled) continue; g_hash_table_add ( hash, GINT_TO_POINTER (ecol->spec->model_col)); } count = e_table_header_count (etfci->full_header); for (i = 0; i < count; i++) { ETableCol *ecol; gpointer key; ecol = e_table_header_get_column (etfci->full_header, i); key = GINT_TO_POINTER (ecol->spec->model_col); if (ecol->spec->disabled) continue; if (!g_hash_table_contains (hash, key)) e_table_header_add_column ( etfci->combined_header, ecol, -1); } g_hash_table_destroy (hash); }
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; }
/* atk table */ static AtkObject * eti_ref_at (AtkTable *table, gint row, gint column) { ETableItem *item; AtkObject * ret; GalA11yETableItemPrivate *priv = GET_PRIVATE (table); if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) return NULL; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); if (!item) return NULL; if (column >= 0 && column < item->cols && row >= 0 && row < item->rows && item->cell_views_realized) { ECellView *cell_view = item->cell_views[column]; ETableCol *ecol = e_table_header_get_column (item->header, column); ret = gal_a11y_e_cell_registry_get_object ( NULL, item, cell_view, ATK_OBJECT (table), ecol->spec->model_col, column, row); if (ATK_IS_OBJECT (ret)) { g_object_weak_ref ( G_OBJECT (ret), (GWeakNotify) cell_destroyed, ret); /* if current cell is focused, add FOCUSED state */ if (e_selection_model_cursor_row (item->selection) == GAL_A11Y_E_CELL (ret)->row && e_selection_model_cursor_col (item->selection) == GAL_A11Y_E_CELL (ret)->model_col) gal_a11y_e_cell_add_state ( GAL_A11Y_E_CELL (ret), ATK_STATE_FOCUSED, FALSE); } else ret = NULL; return ret; } return NULL; }
/* 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; }
inline static gint model_to_view_col (ETableItem *eti, gint model_col) { gint i; if (model_col == -1) return -1; for (i = 0; i < eti->cols; i++) { ETableCol *ecol = e_table_header_get_column (eti->header, i); if (ecol->spec->model_col == model_col) return i; } return -1; }
static void etfci_draw (GnomeCanvasItem *item, cairo_t *cr, gint x, gint y, gint width, gint height) { ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item); GnomeCanvas *canvas = item->canvas; gint rows; gint y1, y2; gint row; if (etfci->combined_header == NULL) return; rows = e_table_header_count (etfci->combined_header); y1 = y2 = 0; for (row = 0; row < rows; row++, y1 = y2) { ETableCol *ecol; ecol = e_table_header_get_column (etfci->combined_header, row); if (ecol->spec->disabled) continue; y2 += e_table_header_compute_height (ecol, GTK_WIDGET (canvas)); if (y1 > (y + height)) break; if (y2 < y) continue; cairo_save (cr); e_table_header_draw_button ( cr, ecol, GTK_WIDGET (canvas), -x, y1 - y, width, height, etfci->width, y2 - y1, E_TABLE_COL_ARROW_NONE); cairo_restore (cr); } }
static const gchar * eti_get_column_description (AtkTable *table, gint column) { ETableItem *item; ETableCol *ecol; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); if (!item) return NULL; ecol = e_table_header_get_column (item->header, column); return ecol->text; }
/* Static functions */ static const gchar * gal_a11y_e_cell_get_name (AtkObject *a11y) { GalA11yECell *cell = GAL_A11Y_E_CELL (a11y); ETableCol *ecol; if (a11y->name != NULL && strcmp (a11y->name, "")) return a11y->name; if (cell->item != NULL) { ecol = e_table_header_get_column (cell->item->header, cell->view_col); if (ecol != NULL) return ecol->text; } return _("Table Cell"); }
static AtkObject * eti_get_column_header (AtkTable *table, gint column) { ETableItem *item; ETableCol *ecol; AtkObject *atk_obj = NULL; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); if (!item) return NULL; ecol = e_table_header_get_column (item->header, column); if (ecol) { atk_obj = gal_a11y_e_table_column_header_new (ecol, item, ATK_OBJECT (table)); } return atk_obj; }
ETableHeader * e_table_state_to_header (GtkWidget *widget, ETableHeader *full_header, ETableState *state) { ETableHeader *nh; const gint max_cols = e_table_header_count (full_header); gint column; GValue *val = g_new0 (GValue, 1); g_return_val_if_fail (widget, NULL); g_return_val_if_fail (full_header, NULL); g_return_val_if_fail (state, NULL); nh = e_table_header_new (); g_value_init (val, G_TYPE_DOUBLE); g_value_set_double (val, e_table_header_width_extras (widget)); g_object_set_property (G_OBJECT(nh), "width_extras", val); g_free (val); for (column = 0; column < state->col_count; column++) { gint col; gdouble expansion; ETableCol *table_col; col = state->columns[column]; expansion = state->expansions[column]; if (col >= max_cols) continue; table_col = e_table_header_get_column (full_header, col); if (expansion >= -1) table_col->expansion = expansion; e_table_header_add_column (nh, table_col, -1); } return nh; }
/* 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 gint etfci_find_button (ETableFieldChooserItem *etfci, gdouble loc) { gint i; gint count; gdouble height = 0; count = e_table_header_count (etfci->combined_header); for (i = 0; i < count; i++) { ETableCol *ecol; ecol = e_table_header_get_column (etfci->combined_header, i); if (ecol->spec->disabled) continue; height += e_table_header_compute_height ( ecol, GTK_WIDGET (GNOME_CANVAS_ITEM (etfci)->canvas)); if (height > loc) return i; } return MAX (0, count - 1); }
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); }
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); }
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); }