Exemple #1
0
/**
 * goc_canvas_get_item_at:
 * @canvas: #GocCanvas
 * @x: horizontal position
 * @y: vertical position
 *
 * Returns: (transfer none): the #GocItem displayed at (@x,@y) if any.
 **/
GocItem*
goc_canvas_get_item_at (GocCanvas *canvas, double x, double y)
{
	GocItem *result = NULL;
	double d = goc_item_distance (GOC_ITEM (canvas->root), x, y, &result);
	return (d == 0.)? result: NULL;
}
Exemple #2
0
static void
ig_reload_style (GnmItemGrid *ig)
{
	GocItem *item = GOC_ITEM (ig);
	GtkStyleContext *context = goc_item_get_style_context (item);
	GtkBorder border;
	GtkStateFlags state = GTK_STATE_FLAG_NORMAL;
	GnmPane *pane = GNM_PANE (item->canvas);

	gtk_style_context_save (context);
	gtk_style_context_add_region (context, "function-marker", 0);
	gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL,
				     &ig->function_marker_color);
	gtk_style_context_get_border_color (context, state,
					    &ig->function_marker_border_color);
	gtk_style_context_restore (context);

	gtk_style_context_save (context);
	gtk_style_context_add_region (context, "pane-divider", 0);
	gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL,
				     &ig->pane_divider_color);
	gtk_style_context_get_border (context, GTK_STATE_FLAG_NORMAL, &border);
	ig->pane_divider_width = border.top;  /* Hack? */
	gtk_style_context_restore (context);

	/* ---------------------------------------- */

	context = gtk_widget_get_style_context (GTK_WIDGET (pane));
	gtk_widget_style_get (GTK_WIDGET (pane),
			      "function-indicator-size",
			      &ig->function_marker_size,
			      NULL);
}
Exemple #3
0
static void
goc_canvas_unrealize (GtkWidget *widget)
{
	GocCanvas *canvas = GOC_CANVAS (widget);

	GOC_ITEM_GET_CLASS (canvas->root)->unrealize (GOC_ITEM (canvas->root));

	GTK_WIDGET_CLASS (parent_klass)->unrealize (widget);
}
static void
comment_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible)
{
	CommentView *cv = (CommentView *)sov;
	GocPoints *points = goc_points_new (3);
	GocItem *item = GOC_ITEM (GOC_GROUP (sov)->children->data);
	if (visible) {
		SheetObject *so = sheet_object_view_get_so (sov);
		SheetControlGUI const *scg = GNM_SIMPLE_CANVAS (item->canvas)->scg;
		double scale;
		gint64 x, y, dx;
		int far_col;
		GnmRange const *r = gnm_sheet_merge_is_corner (so->sheet,
			&so->anchor.cell_bound.start);

		scale = 1. / item->canvas->pixels_per_unit;

		if (r != NULL)
			far_col = 1 + r->end.col;
		else
			far_col = 1 + so->anchor.cell_bound.start.col;

		/* TODO : This could be optimized using the offsets associated with the visible region */
		/* Add 1 to y because we measure from start, x is measured from end, so
		 * it does not need it */
		y = scg_colrow_distance_get (scg, FALSE, 0, so->anchor.cell_bound.start.row)+ 1;
		points->points[0].y = scale * y;
		points->points[1].y = scale * y;
		points->points[2].y = scale * y + cv->comment_indicator_size;

		dx = cv->comment_indicator_size;
		x = scg_colrow_distance_get (scg, TRUE, 0, far_col);
		points->points[0].x = scale * x - dx;
		points->points[1].x = scale * x;
		points->points[2].x = scale * x;

		goc_item_set (item, "points", points, NULL);
		goc_points_unref (points);
		goc_item_show (GOC_ITEM (sov));
	} else
		goc_item_hide (GOC_ITEM (sov));
}
Exemple #5
0
static void
goc_image_set_property (GObject *gobject, guint param_id,
				    GValue const *value, GParamSpec *pspec)
{
	GocImage *image = GOC_IMAGE (gobject);

	switch (param_id) {
	case IMAGE_PROP_X:
		image->x = g_value_get_double (value);
		break;

	case IMAGE_PROP_Y:
		image->y = g_value_get_double (value);
		break;

	case IMAGE_PROP_W:
		image->width = g_value_get_double (value);
		break;

	case IMAGE_PROP_H:
		image->height = g_value_get_double (value);
		break;

	case IMAGE_PROP_ROTATION:
		image->rotation = g_value_get_double (value);
		break;

	case IMAGE_PROP_IMAGE:
		if (image->image)
			g_object_unref (image);
		image->image = GO_IMAGE (g_object_ref (g_value_get_object (value)));
		break;

	case IMAGE_PROP_CROP_BOTTOM:
		image->crop_bottom = g_value_get_double (value);
		break;
	case IMAGE_PROP_CROP_LEFT:
		image->crop_left = g_value_get_double (value);
		break;
	case IMAGE_PROP_CROP_RIGHT:
		image->crop_right = g_value_get_double (value);
		break;
	case IMAGE_PROP_CROP_TOP:
		image->crop_top = g_value_get_double (value);
		break;

	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
		return; /* NOTE : RETURN */
	}
	goc_item_bounds_changed (GOC_ITEM (gobject));

}
/* Somewhat magic.
 * We do not honour all of the anchor flags.  All that is used is the far corner. */
static void
vcombo_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible)
{
	GocGroup *view = GOC_GROUP (sov);

	if (visible) {
		double scale = goc_canvas_get_pixels_per_unit (GOC_ITEM (view)->canvas);
		double h = (coords[3] - coords[1]) + 1.;
		if (h > 20.)	/* clip vertically */
			h = 20.;
		h /= scale;
		goc_item_set (GOC_ITEM (view->children->data),
			/* put it outside the cell */
			"x",	  ((coords[2] >= 0.)? coords[2] / scale: (coords[0] / scale - h + 1.)),
			"y",	  coords [3] / scale - h + 1.,
			"width",  h,	/* force a square, use h for width too */
			"height", h,
			NULL);
		goc_item_show (GOC_ITEM (view));
	} else
		goc_item_hide (GOC_ITEM (view));
}
Exemple #7
0
/**
 * goc_canvas_set_pixels_per_unit:
 * @canvas: #GocCanvas
 * @pixels_per_unit: the new scale
 *
 * Sets the scale as the number of pixels used for each unit when
 * displaying the canvas.
 **/
void
goc_canvas_set_pixels_per_unit (GocCanvas *canvas, double pixels_per_unit)
{
	GocItemClass *klass;
	g_return_if_fail (GOC_IS_CANVAS (canvas));
	if (pixels_per_unit == canvas->pixels_per_unit)
		return;
	klass = GOC_ITEM_GET_CLASS (canvas->root);
	canvas->pixels_per_unit = pixels_per_unit;
	klass->notify_scrolled (GOC_ITEM (canvas->root));
#ifdef GOFFICE_WITH_GTK
	gtk_widget_queue_draw_area (GTK_WIDGET (canvas),
					    0, 0, G_MAXINT, G_MAXINT);
#endif
}
static gboolean
ccombo_activate (GtkTreeView *list, gboolean button)
{
	SheetObjectView		*sov    = g_object_get_data (G_OBJECT (list), SOV_ID);
	GocItem			*view   = GOC_ITEM (sov);
	GnmPane			*pane   = GNM_PANE (view->canvas);
	GnmCComboViewClass	*klass  = GNM_CCOMBO_VIEW_GET_CLASS (sov);

	if ((klass->activate) (sheet_object_view_get_so (sov), list,
			       scg_wbcg (pane->simple.scg), button))
	{
		ccombo_popup_destroy (GTK_WIDGET (list));
		return TRUE;
	}
	return FALSE;
}
Exemple #9
0
/**
 * goc_canvas_scroll_to:
 * @canvas: #GocCanvas
 * @x: the horizontal position
 * @y: the vertical position
 *
 * Scrolls the canvas so that the origin of the visible region is at (@x,@y).
 * The origin position depends on the canvas direction (see #GocDirection).
 **/
void
goc_canvas_scroll_to (GocCanvas *canvas, double x, double y)
{
	GocItemClass *klass;
	g_return_if_fail (GOC_IS_CANVAS (canvas));
	if (x == canvas->scroll_x1 && canvas->scroll_y1 == y)
		return;
	klass = GOC_ITEM_GET_CLASS (canvas->root);
	canvas->scroll_x1 = x;
	canvas->scroll_y1 = y;
	klass->notify_scrolled (GOC_ITEM (canvas->root));
#ifdef GOFFICE_WITH_GTK
	gtk_widget_queue_draw_area (GTK_WIDGET (canvas),
					    0, 0, G_MAXINT, G_MAXINT);
#endif
}
static void
comment_view_reload_style (CommentView *cv)
{
	GocItem *item = GOC_ITEM (cv);
	GnmPane *pane = GNM_PANE (item->canvas);
	GtkStyleContext *context;

	context = goc_item_get_style_context (item);
	gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL,
				     &cv->comment_indicator_color);

	context = gtk_widget_get_style_context (GTK_WIDGET (pane));
	gtk_widget_style_get (GTK_WIDGET (pane),
			      "comment-indicator-size",
			      &cv->comment_indicator_size,
			      NULL);
}
Exemple #11
0
static void
gnm_item_grid_init (GnmItemGrid *ig)
{
	GocItem *item = GOC_ITEM (ig);

	item->x0 = 0;
	item->y0 = 0;
	item->x1 = 0;
	item->y1 = 0;

	ig->selecting = GNM_ITEM_GRID_NO_SELECTION;
	/* We need something at least as big as any sheet.  */
	ig->bound.start.col = ig->bound.start.row = 0;
	ig->bound.end.col = GNM_MAX_COLS - 1;
	ig->bound.end.row = GNM_MAX_ROWS - 1;
	ig->cursor_timer = 0;
	ig->cur_link = NULL;
	ig->tip_timer = 0;
	ig->tip = NULL;
}
Exemple #12
0
static void
goc_polyline_set_property (GObject *gobject, guint param_id,
				    GValue const *value, GParamSpec *pspec)
{
	GocPolyline *polyline = GOC_POLYLINE (gobject);

	switch (param_id) {
	case POLYLINE_PROP_POINTS: {
		unsigned i;
		GocPoints *points = (GocPoints *) g_value_get_boxed (value);
		polyline->nb_points = points->n;
		g_free (polyline->points);
		if (points->n > 0) {
			polyline->points = g_new (GocPoint, points->n);
			for (i = 0; i < points->n; i++)
				polyline->points[i] = points->points[i];
		} else
			polyline->points = NULL;
		break;
	}
	case POLYLINE_PROP_SPLINE:
		polyline->use_spline = g_value_get_boolean (value);
		break;

	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
		return; /* NOTE : RETURN */
	}
	if (polyline->use_spline && polyline->nb_points) {
		double *x, *y;
		unsigned i;
		x = g_alloca (polyline->nb_points * sizeof (double));
		y = g_alloca (polyline->nb_points * sizeof (double));
		for (i = 0; i < polyline->nb_points; i++) {
			x[i] = polyline->points[i].x - polyline->points[0].x;
			y[i] = polyline->points[i].y - polyline->points[0].y;
		}
		g_object_set_data_full (G_OBJECT (polyline), "spline", go_bezier_spline_init (x, y, polyline->nb_points, FALSE), (GDestroyNotify) go_bezier_spline_destroy);
	}
	goc_item_bounds_changed (GOC_ITEM (gobject));
}
Exemple #13
0
static gboolean
ig_obj_create_begin (GnmItemGrid *ig, int button, gint64 x, gint64 y)
{
	GnmPane *pane = GNM_PANE (GOC_ITEM (ig)->canvas);
	SheetObject *so = ig->scg->wbcg->new_object;
	SheetObjectAnchor anchor;
	double coords[4];

	g_return_val_if_fail (ig->scg->selected_objects == NULL, TRUE);
	g_return_val_if_fail (so != NULL, TRUE);

	coords[0] = coords[2] = x;
	coords[1] = coords[3] = y;
	sheet_object_anchor_init (&anchor, NULL, NULL, GOD_ANCHOR_DIR_DOWN_RIGHT);
	scg_object_coords_to_anchor (ig->scg, coords, &anchor);
	sheet_object_set_anchor (so, &anchor);
	sheet_object_set_sheet (so, scg_sheet (ig->scg));
	scg_object_select (ig->scg, so);
	gnm_pane_object_start_resize (pane, button, x, y, so, 7, TRUE);

	return TRUE;
}
Exemple #14
0
static void
preview_grid_set_property (GObject *obj, guint param_id,
			   GValue const *value, GParamSpec *pspec)
{
	GnmPreviewGrid *pg = GNM_PREVIEW_GRID (obj);

	switch (param_id){
	case PREVIEW_GRID_PROP_RENDER_GRIDLINES :
		pg->gridlines = g_value_get_boolean (value);
		break;
	case PREVIEW_GRID_PROP_DEFAULT_COL_WIDTH :
		pg->defaults.col_width = g_value_get_uint (value);
		break;
	case PREVIEW_GRID_PROP_DEFAULT_ROW_HEIGHT :
		pg->defaults.row_height = g_value_get_uint (value);
		break;
	case PREVIEW_GRID_PROP_DEFAULT_STYLE : { /* add a  ref */
		GnmStyle *style = g_value_get_pointer (value);
		g_return_if_fail (style != NULL);
		gnm_style_ref (style);
		gnm_style_unref (pg->defaults.style);
		pg->defaults.style = style;
		break;
	}
	case PREVIEW_GRID_PROP_DEFAULT_VALUE : { /* steal ownership */
		GnmValue *val = g_value_get_pointer (value);
		g_return_if_fail (val != NULL);
		if (pg->defaults.value != val) {
			value_release (pg->defaults.value);
			pg->defaults.value = val;
		}
		break;
	}
	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
		return; /* NOTE : RETURN */
	}

	goc_item_invalidate (GOC_ITEM (obj));
}
Exemple #15
0
static SheetObjectView *
gnm_so_path_new_view (SheetObject *so, SheetObjectViewContainer *container)
{
	GnmSOPath *sop = GNM_SO_PATH (so);
	GnmSOPathView *item;
	/* FIXME: this is unsafe if the paths change after the view is created,
	 * but this can't occur for now */
	unsigned i;

	if (sop->path == NULL && sop->paths == NULL)
		return NULL;
	item = (GnmSOPathView *) goc_item_new (
	                            gnm_pane_object_group (GNM_PANE (container)),
	                            so_path_goc_view_get_type (),
	                            NULL);
	if (sop->path)
		item->path = goc_item_new (GOC_GROUP (item),
		                           GOC_TYPE_PATH,
		                           "closed", TRUE,
		                           "fill-rule", TRUE,
		                           NULL);
	else {
		item->paths = g_ptr_array_sized_new (sop->paths->len);
		g_ptr_array_set_free_func (item->paths, g_object_unref);
		for (i = 0; i < sop->paths->len; i++)
			g_ptr_array_add (item->paths,
				             goc_item_new (GOC_GROUP (item),
				                           GOC_TYPE_PATH,
				                           "closed", TRUE,
				                           "fill-rule", TRUE,
				                           NULL));
	}
	cb_gnm_so_path_changed (sop, NULL, item);
	g_signal_connect_object (sop,
		"notify::style", G_CALLBACK (cb_gnm_so_path_changed),
		item, 0);
	return gnm_pane_object_register (so, GOC_ITEM (item), TRUE);
}
static void
so_image_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible)
{
	GocItem *view = GOC_ITEM (GOC_GROUP (sov)->children->data);
	double scale = goc_canvas_get_pixels_per_unit (view->canvas);

	if (visible) {
		double x, y, width, height;
		double old_x1, old_y1, old_x2, old_y2, old_width, old_height;
		GdkPixbuf *placeholder = g_object_get_data (G_OBJECT (view), "tile");

		x = MIN (coords [0], coords [2]) / scale;
		y = MIN (coords [1], coords [3]) / scale;
		width  = fabs (coords [2] - coords [0]) / scale;
		height = fabs (coords [3] - coords [1]) / scale;

		goc_item_get_bounds (view, &old_x1, &old_y1, &old_x2, &old_y2);
		goc_item_set (view,
			"x", x,			"y", y,
			"width",  width,	"height", height,
			NULL);

		/* regenerate the image if necessary */
		old_width = fabs (old_x1 - old_x2);
		old_height = fabs (old_y1 - old_y2);
		if (placeholder != NULL &&
		    (fabs (width - old_width) > 0.5 || fabs (height - old_height) > 0.5)) {
			GdkPixbuf *newimage = go_pixbuf_tile (placeholder,
				(guint)width, (guint)height);
			goc_item_set (view, "pixbuf", newimage, NULL);
			g_object_unref (newimage);
		}

		goc_item_show (view);
	} else
		goc_item_hide (view);
}
Exemple #17
0
static void
goc_line_set_property (GObject *gobject, guint param_id,
				    GValue const *value, GParamSpec *pspec)
{
	GocLine *line = GOC_LINE (gobject);

	switch (param_id) {
	case LINE_PROP_X0:
		line->startx = g_value_get_double (value);
		break;

	case LINE_PROP_Y0:
		line->starty = g_value_get_double (value);
		break;

	case LINE_PROP_X1:
		line->endx = g_value_get_double (value);
		break;

	case LINE_PROP_Y1:
		line->endy = g_value_get_double (value);
		break;

	case LINE_PROP_START_ARROW:
		line->start_arrow = *((GOArrow *)g_value_peek_pointer (value));
		break;

	case LINE_PROP_END_ARROW:
		line->end_arrow = *((GOArrow *)g_value_peek_pointer (value));
		break;

	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
		return; /* NOTE : RETURN */
	}
	goc_item_bounds_changed (GOC_ITEM (gobject));
}
Exemple #18
0
static void
cb_gnm_so_path_changed (GnmSOPath const *sop,
			G_GNUC_UNUSED GParamSpec *pspec,
			GnmSOPathView *group)
{
	GList *ptr = GOC_GROUP (group)->children;
	for (; ptr && ptr->data; ptr = ptr->next)
		if (GOC_IS_PATH (ptr->data))
			cb_gnm_so_path_style_changed (GOC_ITEM (ptr->data), sop);

	if (sop->text != NULL && *sop->text != 0) {
		/* set a font, a very bad solution, but will do until we move to GOString */
		PangoFontDescription *desc = pango_font_description_from_string ("Sans 10");
		GOStyle *style;
		if (group->text == NULL) {
			double x0, y0, x1, y1;
			if (group->path)
				goc_item_get_bounds (group->path, &x0, &y0, &x1, &y1);
			else {
				unsigned i;
				double mx, my, Mx, My;
				x0 = y0 = G_MAXDOUBLE;
				x1 = y1 = -G_MAXDOUBLE;
				for (i = 0; i < group->paths->len; i++) {
					goc_item_get_bounds (GOC_ITEM (g_ptr_array_index (group->paths, i)), &mx, &my, &Mx, &My);
					if (mx < x0)
						x0 = mx;
					if (my < y0)
						y0 = my;
					if (Mx > x1)
						x1 = Mx;
					if (My > y1)
						y1 = My;
				}
			}
			x1 -= x0 + sop->margin_pts.left + sop->margin_pts.right;
			y1 -= y0 + sop->margin_pts.top + sop->margin_pts.bottom;
			x0 += x1 / 2. + sop->margin_pts.left;
			y0 += y1 / 2. + sop->margin_pts.top;
			x1 = MAX (x1, DBL_MIN);
			y1 = MAX (y1, DBL_MIN);
			group->text = goc_item_new (GOC_GROUP (group), GOC_TYPE_TEXT,
				"anchor",	GO_ANCHOR_CENTER,
				"clip",		TRUE,
				"x",		x0,
				"y",		y0,
		        "clip-height", y1,
		        "clip-width",  x1,
		        "wrap-width",  x1,
				"attributes",	sop->markup,
				NULL);
		}
		style = go_styled_object_get_style (GO_STYLED_OBJECT (group->text));
		go_style_set_font_desc (style, desc);
		goc_item_set (group->text,
				     "text", sop->text,
				     "attributes",	sop->markup,
				     NULL);
	} else if (group->text != NULL) {
		g_object_unref (group->text);
		group->text = NULL;
	}
}
Exemple #19
0
static void
so_path_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible)
{
	GnmSOPathView *spv = (GnmSOPathView *) sov;

	if (visible) {
		SheetObject		*so   = sheet_object_view_get_so (sov);
		GnmSOPath const	*sop  = GNM_SO_PATH (so);
		GOPath *path;
		double scale, x_scale, y_scale, x, y;
		if ((sop->path == NULL && sop->paths == NULL) || sop->width <=0. || sop->height <=0.)
			return;

		scale = goc_canvas_get_pixels_per_unit (GOC_ITEM (sov)->canvas);
		x_scale = fabs (coords[2] - coords[0]) / sop->width / scale;
		y_scale = fabs (coords[3] - coords[1]) / sop->height / scale;
		x = MIN (coords[0], coords[2]) / scale - sop->x_offset * x_scale;
		y = MIN (coords[1], coords[3]) / scale - sop->y_offset * y_scale;

		if (sop->path != NULL) {
			path = go_path_scale (sop->path, x_scale, y_scale);
			goc_item_set (spv->path, "x", x, "y", y, "path", path, NULL);
			go_path_free (path);
		} else {
			unsigned i;
			for (i = 0; i < sop->paths->len; i++) {
				path = go_path_scale ((GOPath *) g_ptr_array_index (sop->paths, i), x_scale, y_scale);
				goc_item_set (GOC_ITEM (g_ptr_array_index (spv->paths, i)), "x", x, "y", y, "path", path, NULL);
				go_path_free (path);
			}
		}

		if (spv->text != NULL && GOC_ITEM (spv->text)) {
			double x0, y0, x1, y1;
			if (spv->path)
				goc_item_get_bounds (spv->path, &x0, &y0, &x1, &y1);
			else {
				unsigned i;
				double mx, my, Mx, My;
				x0 = y0 = G_MAXDOUBLE;
				x1 = y1 = -G_MAXDOUBLE;
				for (i = 0; i < spv->paths->len; i++) {
					goc_item_get_bounds (GOC_ITEM (g_ptr_array_index (spv->paths, i)), &mx, &my, &Mx, &My);
					if (mx < x0)
						x0 = mx;
					if (my < y0)
						y0 = my;
					if (Mx > x1)
						x1 = Mx;
					if (My > y1)
						y1 = My;
				}
			}
			x1 -= x0 + sop->margin_pts.left + sop->margin_pts.right;
			y1 -= y0 + sop->margin_pts.top + sop->margin_pts.bottom;
			x0 += x1 / 2. + sop->margin_pts.left;
			y0 += y1 / 2. + sop->margin_pts.top;
			x1 = MAX (x1, DBL_MIN);
			y1 = MAX (y1, DBL_MIN);

			goc_item_set (GOC_ITEM (spv->text),
			              "x", x0,
			              "y", y0,
				          "clip-height", y1,
				          "clip-width",  x1,
				          "wrap-width",  x1,
				          NULL);
		}
	} else
		goc_item_hide (GOC_ITEM (sov));
}
Exemple #20
0
/**
 * gnm_cell_combo_view_popdown:
 * @sov: #SheetObjectView
 * @activate_time: event time
 *
 * Open the popup window associated with @sov
 **/
void
gnm_cell_combo_view_popdown (SheetObjectView *sov, guint32 activate_time)
{
	GocItem		   *view   = GOC_ITEM (sov);
	GnmPane		   *pane   = GNM_PANE (view->canvas);
	SheetControlGUI	   *scg    = pane->simple.scg;
	SheetObject	   *so     = sheet_object_view_get_so (sov);
	Sheet const	   *sheet  = sheet_object_get_sheet (so);
	GtkWidget *frame,  *popup, *list, *container;
	int root_x, root_y;
	gboolean 	make_buttons = FALSE;
	GtkTreePath	  *clip = NULL, *select = NULL;
	GtkWindow *toplevel = wbcg_toplevel (scg_wbcg (scg));
	GdkWindow *popup_window;
	GdkDevice *device;
	GnmRange const *merge;

	popup = gtk_window_new (GTK_WINDOW_POPUP);

	gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_COMBO);
	gtk_window_group_add_window (gtk_window_get_group (toplevel), GTK_WINDOW (popup));
	go_gtk_window_set_transient (toplevel, GTK_WINDOW (popup));
	gtk_window_set_resizable (GTK_WINDOW (popup), FALSE);
	gtk_window_set_decorated (GTK_WINDOW (popup), FALSE);
	gtk_window_set_screen (GTK_WINDOW (popup),
		gtk_widget_get_screen (GTK_WIDGET (toplevel)));

	list = ccombo_create_list (GNM_CCOMBO_VIEW (sov), so, &clip, &select, &make_buttons);

	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
	g_object_set_data (G_OBJECT (list), SOV_ID, sov);

	frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);

#if 0
	range_dump (&so->anchor.cell_bound, "");
	g_printerr (" : so = %p, view = %p\n", so, view);
#endif
	if (clip != NULL) {
		GtkWidget *sw = gtk_scrolled_window_new (
			gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (list)),
			gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (list)));
		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
						GTK_POLICY_AUTOMATIC,
						GTK_POLICY_ALWAYS);
		g_object_set_data_full (G_OBJECT (list),
					"clip", clip,
					(GDestroyNotify)gtk_tree_path_free);

		gtk_container_add (GTK_CONTAINER (sw), list);

		/*
		 * Do the sizing in a realize handler as newer versions of
		 * gtk+ give us zero sizes until then.
		 */
		g_signal_connect_after (list, "realize",
					G_CALLBACK (cb_realize_treeview),
					sw);
		container = sw;
	} else
		container = list;

	if (make_buttons) {
		GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
		GtkWidget *hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);

		GtkWidget *button;
		button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
		g_signal_connect_swapped (button, "clicked",
			G_CALLBACK (cb_ccombo_cancel_button), list);
		gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 6);
		button = gtk_button_new_from_stock (GTK_STOCK_OK);
		g_signal_connect_swapped (button, "clicked",
			G_CALLBACK (cb_ccombo_ok_button), list);
		gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 6);

		gtk_box_pack_start (GTK_BOX (vbox), container, FALSE, TRUE, 6);
		gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 6);
		container = vbox;
	}

	gtk_container_add (GTK_CONTAINER (frame), container);

	/* do the popup */
	gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (pane)),
			       &root_x, &root_y);
	if (sheet->text_is_rtl) {
		GtkAllocation pa;
		gtk_widget_get_allocation (GTK_WIDGET (pane), &pa);
		root_x += pa.width;
		root_x -= scg_colrow_distance_get (scg, TRUE,
			pane->first.col,
			so->anchor.cell_bound.start.col + 1);
	} else
		root_x += scg_colrow_distance_get (scg, TRUE,
			pane->first.col,
			so->anchor.cell_bound.start.col);
	merge = gnm_sheet_merge_is_corner (sheet, &(so->anchor.cell_bound.start));
	gtk_window_move (GTK_WINDOW (popup), root_x,
		root_y + scg_colrow_distance_get
			 (scg, FALSE,
			  pane->first.row,
			  so->anchor.cell_bound.start.row +
			  ((merge == NULL) ? 1 : range_height (merge))));

	gtk_container_add (GTK_CONTAINER (popup), frame);

	g_signal_connect (popup, "key_press_event",
		G_CALLBACK (cb_ccombo_key_press), list);
	g_signal_connect (popup, "button_press_event",
		G_CALLBACK (cb_ccombo_button_press), list);
	g_signal_connect_after (popup, "button_release_event",
		G_CALLBACK (cb_ccombo_button_release), list);
	g_signal_connect (list, "motion_notify_event",
		G_CALLBACK (cb_ccombo_list_motion), list);
	g_signal_connect (list, "button_press_event",
		G_CALLBACK (cb_ccombo_list_button_press), popup);

	gtk_widget_show_all (popup);

	/* after we show the window setup the selection (showing the list
	 * clears the selection) */
	if (select != NULL) {
		gtk_tree_selection_select_path (
			gtk_tree_view_get_selection (GTK_TREE_VIEW (list)),
			select);
		gtk_tree_view_set_cursor (GTK_TREE_VIEW (list),
			select, NULL, FALSE);
		gtk_tree_path_free (select);
	}

	gtk_widget_grab_focus (popup);
	gtk_widget_grab_focus (GTK_WIDGET (list));
	ccombo_focus_change (GTK_WIDGET (list), TRUE);

	popup_window = gtk_widget_get_window (popup);

	device = gtk_get_current_event_device ();
	if (0 == gdk_device_grab (device, popup_window,
	                          GDK_OWNERSHIP_APPLICATION, TRUE,
	                          GDK_BUTTON_PRESS_MASK |
	                          GDK_BUTTON_RELEASE_MASK |
	                          GDK_POINTER_MOTION_MASK,
	                          NULL, activate_time)) {
		if (0 == gdk_device_grab (gdk_device_get_associated_device (device),
		                          popup_window,
		                          GDK_OWNERSHIP_APPLICATION, TRUE,
		                          GDK_KEY_PRESS_MASK |
		                          GDK_KEY_RELEASE_MASK,
		                          NULL, activate_time))
			gtk_grab_add (popup);
		else
			gdk_device_ungrab (device, activate_time);
	}
}
Exemple #21
0
void
goc_canvas_get_bounds (GocCanvas *canvas, double *x0, double *y0, double *x1, double *y1)
{
	goc_item_get_bounds (GOC_ITEM (canvas->root), x0, y0, x1, y1);
}
Exemple #22
0
void
goc_canvas_render (GocCanvas *canvas, cairo_t *cr, double x0, double y0, double x1, double y1)
{
	goc_item_draw_region (GOC_ITEM (canvas->root), cr, x0, y0, x1, y1);
}
Exemple #23
0
static void
goc_component_set_property (GObject *obj, guint param_id,
			GValue const *value, GParamSpec *pspec)
{
	GocComponent *component = GOC_COMPONENT (obj);

	switch (param_id) {
	case COMPONENT_PROP_X: {
		double x = g_value_get_double (value);
		if (x == component->x)
			return;
		component->x = x;
		return;
	}
	case COMPONENT_PROP_Y: {
		double y = g_value_get_double (value);
		if (y == component->y)
			return;
		component->y = y;
		break;
	}
	/* NOTE: it is allowed to set width and height even if the component is not resizable
	 * but this should be only used to convert the size in inches to pixels.
	 * The default is 1 pixel == 1 point.
	 */
	case COMPONENT_PROP_H: {
		double h = g_value_get_double (value);
		if (!component->component || h == component->h)
			return;
		component->h = h;
		break;
	}
	case COMPONENT_PROP_W: {
		double w = g_value_get_double (value);
		if (!component->component || w == component->w)
			return;
		component->w = w;
		break;
	}
	case COMPONENT_PROP_ROTATION: {
		double r = g_value_get_double (value) / 180. * M_PI;
		if (!component->component || r == component->rotation)
			return;
		component->rotation = r;
		break;
	}

	case COMPONENT_PROP_OBJECT:
		if (component->component != NULL)
			g_object_unref (component->component);
		component->component = GO_COMPONENT (g_value_get_object (value));
		if (component->component != NULL) {
			g_object_ref (component->component);
			/* set default or fixed size */
			if (component->w == 0 || component->h == 0 || !go_component_is_resizable (component->component)) {
				go_component_get_size (component->component, &component->w, &component->h);
				component->w = GO_IN_TO_PT (component->w);
				component->h = GO_IN_TO_PT (component->h);
			}
		}
		break;

	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
		return; /* NOTE : RETURN */
	}

	goc_item_bounds_changed (GOC_ITEM (component));
}
Exemple #24
0
static gboolean
goc_canvas_draw (GtkWidget *widget, cairo_t *cr)
{
	double x0, y0, x1, y1;
	double ax0, ay0, ax1, ay1;
	double clip_x1, clip_y1, clip_x2, clip_y2;
	GocCanvas *canvas = GOC_CANVAS (widget);
	GdkEventExpose *event = (GdkEventExpose *) gtk_get_current_event ();
	GocCanvasPrivate *priv = (GocCanvasPrivate *) canvas->priv;
	cairo_rectangle_list_t *l = cairo_copy_clip_rectangle_list (cr);
	int i, x, y;

	if (GOC_IS_ITEM (priv->invalidated_item) && priv->invalid_region) {
		/* evaluate the cairo clipped region and compare with the saved one */
		cairo_region_t *region;
		cairo_rectangle_int_t rect[l->num_rectangles];
	    for (i= 0; i  < l->num_rectangles; i++) {
			rect[i].x = l->rectangles[i].x;
			rect[i].y = l->rectangles[i].y;
			rect[i].width = l->rectangles[i].width;
			rect[i].height = l->rectangles[i].height;
		}
		region = cairo_region_create_rectangles (rect, l->num_rectangles);
		if (cairo_region_equal (priv->invalid_region, region)) {
			cairo_rectangle_list_destroy (l);
			cairo_region_destroy (region);
			/* looks like each time we call gtk_widget_queue_draw*,
			   the draw event is fired twice */
			if (priv->done) {
				priv->invalidated_item = NULL;
				cairo_region_destroy (priv->invalid_region);
				priv->invalid_region = NULL;
			} else {
				goc_item_draw (priv->invalidated_item, cr);
				priv->done = TRUE;
			}
			return TRUE;
		}

		cairo_region_destroy (region);
	}

	x = gtk_adjustment_get_value (gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas)));
	y = gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas)));
	cairo_translate (cr, -x, -y);
	goc_item_get_bounds (GOC_ITEM (canvas->root),&x0, &y0, &x1, &y1);
	for (i= 0; i  < l->num_rectangles; i++) {
		cairo_save (cr);
		cairo_rectangle (cr, l->rectangles[i].x, l->rectangles[i].y,
		                 l->rectangles[i].width, l->rectangles[i].height);
		cairo_clip (cr);
		clip_x1 = l->rectangles[i].x;
		clip_y1 = l->rectangles[i].y;
		clip_x2 = clip_x1 + l->rectangles[i].width;
		clip_y2 = clip_y1 + l->rectangles[i].height;

		if (canvas->direction == GOC_DIRECTION_RTL) {
			ax1 = (double) (canvas->width - clip_x1) / canvas->pixels_per_unit + canvas->scroll_x1;
			ax0 = (double) (canvas->width - clip_x2) / canvas->pixels_per_unit + canvas->scroll_x1;
		} else {
			ax0 = (double) clip_x1 / canvas->pixels_per_unit + canvas->scroll_x1;
			ax1 = ((double) clip_x1 + event->area.width) / canvas->pixels_per_unit + canvas->scroll_x1;
		}
		ay0 = (double) clip_y1 / canvas->pixels_per_unit + canvas->scroll_y1;
		ay1 = (double) clip_y2 / canvas->pixels_per_unit + canvas->scroll_y1;
		if (x0 <= ax1 && x1 >= ax0 && y0 <= ay1 && y1 >= ay0) {
			canvas->cur_event = (GdkEvent *) event;
			goc_item_draw_region (GOC_ITEM (canvas->root), cr, ax0, ay0, ax1, ay1);
		}
		cairo_restore (cr);
	}
	cairo_rectangle_list_destroy (l);
	return TRUE;
}