コード例 #1
0
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;
}
コード例 #2
0
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);
}
コード例 #3
0
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;
}
コード例 #4
0
/**
 * 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;
}
コード例 #5
0
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);
}
コード例 #6
0
/* 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;
}
コード例 #7
0
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);
	}
}
コード例 #8
0
ファイル: e-table-utils.c プロジェクト: jdapena/evolution
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;
}
コード例 #9
0
/* 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;
}
コード例 #10
0
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);
}
コード例 #11
0
ファイル: e-table-sorter.c プロジェクト: Distrotech/evolution
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);
}
コード例 #12
0
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);
}
コード例 #13
0
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);
}
コード例 #14
0
static int
etgc_event (GnomeCanvasItem *item, GdkEvent *event)
{
	ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(item);
	gboolean return_val = TRUE;
	gboolean change_focus = FALSE;
	gboolean use_col = FALSE;
	gint start_col = 0;
	gint old_col;
	EFocus direction = E_FOCUS_START;

	switch (event->type) {
	case GDK_KEY_PRESS:
		if (event->key.keyval == GDK_Tab ||
		    event->key.keyval == GDK_KP_Tab ||
		    event->key.keyval == GDK_ISO_Left_Tab) {
			change_focus = TRUE;
			use_col      = TRUE;
			start_col    = (event->key.state & GDK_SHIFT_MASK) ? -1 : 0;
			direction    = (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START;
		} else if (event->key.keyval == GDK_Left ||
			   event->key.keyval == GDK_KP_Left) {
			change_focus = TRUE;
			use_col      = TRUE;
			start_col    = -1;
			direction    = E_FOCUS_END;
		} else if (event->key.keyval == GDK_Right ||
			   event->key.keyval == GDK_KP_Right) {
			change_focus = TRUE;
			use_col   = TRUE;
			start_col = 0;
			direction = E_FOCUS_START;
		} else if (event->key.keyval == GDK_Down ||
			   event->key.keyval == GDK_KP_Down) {
			change_focus = TRUE;
			use_col      = FALSE;
			direction    = E_FOCUS_START;
		} else if (event->key.keyval == GDK_Up ||
			   event->key.keyval == GDK_KP_Up) {
			change_focus = TRUE;
			use_col      = FALSE;
			direction    = E_FOCUS_END;
		} else if (event->key.keyval == GDK_Return ||
			   event->key.keyval == GDK_KP_Enter) {
			change_focus = TRUE;
			use_col      = FALSE;
			direction    = E_FOCUS_START;
		}
		if (change_focus){
			GList *list;
			for (list = etgc->children; list; list = list->next) {
				ETableGroupContainerChildNode *child_node;
				ETableGroup                   *child;

				child_node = (ETableGroupContainerChildNode *)list->data;
				child      = child_node->child;

				if (e_table_group_get_focus (child)) {
					old_col = e_table_group_get_focus_column (child);
					if (old_col == -1)
						old_col = 0;
					if (start_col == -1)
						start_col = e_table_header_count (e_table_group_get_header (child)) - 1;

					if (direction == E_FOCUS_END)
						list = list->prev;
					else
						list = list->next;

					if (list) {
						child_node = (ETableGroupContainerChildNode *)list->data;
						child = child_node->child;
						if (use_col)
							e_table_group_set_focus (child, direction, start_col);
						else
							e_table_group_set_focus (child, direction, old_col);
						return 1;
					} else {
						return 0;
					}
				}
			}
			if (direction == E_FOCUS_END)
				list = g_list_last(etgc->children);
			else
				list = etgc->children;
			if (list) {
				ETableGroupContainerChildNode *child_node;
				ETableGroup                   *child;

				child_node = (ETableGroupContainerChildNode *)list->data;
				child = child_node->child;

				if (start_col == -1)
					start_col = e_table_header_count (e_table_group_get_header (child)) - 1;

				e_table_group_set_focus (child, direction, start_col);
				return 1;
			}
		}
		return_val = FALSE;
		break;
	default:
		return_val = FALSE;
		break;
	}
	if (return_val == FALSE) {
		if (GNOME_CANVAS_ITEM_CLASS(etgc_parent_class)->event)
			return GNOME_CANVAS_ITEM_CLASS (etgc_parent_class)->event (item, event);
	}
	return return_val;

}