%%
headers
/* vim: syntax=c
 */
#include <Python.h>
#define NO_IMPORT_PYGOBJECT 1
#define NO_IMPORT_PYGTK 1

#include <pygobject.h>
#include <pygtk/pygtk.h>
#include <diacanvas/dia-canvas.h>
#include <diacanvas/dia-canvas-group.h>
#include <diacanvas/dia-canvas-editable.h>
#include <diacanvas/dia-shape.h>
#include <diacanvas/dia-event.h>
#include <diacanvas/dia-geometry.h>
#include <diacanvas/dia-canvas-i18n.h>
#include <diacanvas/dia-strength.h>
#include <diacanvas/dia-variable.h>
#include <diacanvas/dia-constraint.h>
#include <diacanvas/dia-solver.h>
#include <diacanvas/dia-canvas-line.h>
#include <diacanvas/dia-canvas-element.h>
#include <diacanvas/dia-canvas-box.h>
#include <diacanvas/dia-canvas-text.h>
#include <diacanvas/dia-canvas-image.h>
#include <diacanvas/dia-shape-art.h>
#include <diacanvas/dia-shape-x.h>
#include <diacanvas/dia-export-svg.h>
#include <diacanvas/diatypebuiltins.h>

/* A few macro's to support DiaCanvasGroupable from canvas items. */
#define dia_canvas_item_groupable_add(g,i) dia_canvas_groupable_add(g,i)
#define dia_canvas_item_groupable_remove(g,i) dia_canvas_groupable_remove(g,i)
#define dia_canvas_item_groupable_length(g) dia_canvas_groupable_length(g)
#define dia_canvas_item_groupable_pos(g,i) dia_canvas_groupable_pos(g,i)

static int
canvas_item_set_properties (DiaCanvasItem *item, PyObject *kwargs)
{
	GType type;
	GObjectClass *class;
	int pos = 0;
	PyObject *value;
	PyObject *key;

	type = G_OBJECT_TYPE (item);
	class = G_OBJECT_GET_CLASS (item);
	g_object_freeze_notify (G_OBJECT (item));

	/* For each keyword ... */
	while (kwargs && PyDict_Next (kwargs, &pos, &key, &value)) {
		gchar *key_str = PyString_AsString (key);
		GParamSpec *pspec;
		GValue gvalue ={ 0, };

		pspec = g_object_class_find_property (class, key_str);
		if (!pspec) {
			gchar buf[512];

			g_snprintf (buf, sizeof(buf),
				    "canvas item `%s' doesn't support property `%s'",
				    g_type_name (type), key_str);
			PyErr_SetString (PyExc_TypeError, buf);
			g_object_unref (item);
			return -1;
		}

		g_value_init (&gvalue, G_PARAM_SPEC_VALUE_TYPE (pspec));
		if (pyg_value_from_pyobject (&gvalue, value)) {
			gchar buf[512];

			g_snprintf (buf, sizeof (buf),
				    "could not convert value for property `%s'", key_str);
			PyErr_SetString (PyExc_TypeError, buf);
			g_object_unref (item);
			return -1;
		}
		g_object_set_property (G_OBJECT (item), key_str, &gvalue);
		g_value_unset (&gvalue);
	}

	g_object_thaw_notify (G_OBJECT(item));

	return 0;
}

static int
create_canvas_item (PyGObject *self, PyObject *args, PyObject *kwargs, GType type)
{
	self->obj = (GObject *) dia_canvas_item_create(type, NULL);

	if (!self->obj) {
		gchar buf[512];

		g_snprintf (buf, sizeof (buf),
			    "could not create %s object", g_type_name (type));
		PyErr_SetString (PyExc_TypeError, buf);
		return -1;
	}

	if (canvas_item_set_properties (DIA_CANVAS_ITEM (self->obj), kwargs) != 0)
		return -1;
	
	// TODO: Check for Groupable interface. If so, add weak ref so
	// child items are dia_groupable_remove()'d.

	pygobject_register_wrapper((PyObject *)self);
	return 0;
}

%%
import gobject.GObject as PyGObject_Type
import gtk.gdk.Drawable as PyGdkDrawable_Type
import gtk.gdk.Pixbuf as PyGdkPixbuf_Type
import pango.Layout as PyPangoLayout_Type
%%
ignore-glob
  *_get_type
  _*
%%
ignore
  DiaPoint
  DiaRectangle
  DiaShape
  dia_canvas_group_foreach
  dia_canvas_preserve
  dia_canvas_item_bb_affine
  dia_canvas_view_item_foreach
  dia_handle_set_pos_i_affine
  dia_handle_update_i2w_affine
  dia_handle_update_w2i_affine
  dia_handle_layer_get_pos_c
%%
override dia_canvas_item_new kwargs
static int
_wrap_dia_canvas_item_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_ITEM);
}
%%
override dia_canvas_group_new kwargs
static int
_wrap_dia_canvas_group_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_GROUP);
}
%%
override dia_canvas_element_new kwargs
static int
_wrap_dia_canvas_element_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_ELEMENT);
}
%%
override dia_canvas_line_new kwargs
static int
_wrap_dia_canvas_line_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_LINE);
}
%%
override dia_canvas_box_new kwargs
static int
_wrap_dia_canvas_box_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_BOX);
}
%%
override dia_canvas_image_new kwargs
static int
_wrap_dia_canvas_image_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_IMAGE);
}
%%
override dia_canvas_text_new kwargs
static int
_wrap_dia_canvas_text_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_TEXT);
}
%%
override dia_canvas_item_new kwargs
static int
_wrap_dia_canvas_item_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_ITEM);
}
%%
override dia_canvas_group_new kwargs
static int
_wrap_dia_canvas_group_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_GROUP);
}
%%
override dia_canvas_element_new kwargs
static int
_wrap_dia_canvas_element_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_ELEMENT);
}
%%
override dia_canvas_line_new kwargs
static int
_wrap_dia_canvas_line_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_LINE);
}
%%
override dia_canvas_box_new kwargs
static int
_wrap_dia_canvas_box_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_BOX);
}
%%
override dia_canvas_image_new kwargs
static int
_wrap_dia_canvas_image_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_IMAGE);
}
%%
override dia_canvas_text_new kwargs
static int
_wrap_dia_canvas_text_new (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	return create_canvas_item (self, args, kwargs, DIA_TYPE_CANVAS_TEXT);
}
%%
override dia_canvas_get_pango_layout noargs
static PyObject *
_wrap_dia_canvas_get_pango_layout(PyGObject *self)
{
    PangoLayout *ret;

    ret = dia_canvas_get_pango_layout();
    /* pygobject_new handles NULL checking */
    return pygobject_new((GObject *)ret);
}
%%
override dia_canvas_set_extents kwargs
static PyObject *
_wrap_dia_canvas_set_extents(PyGObject *self, PyObject *args, PyObject *kwargs)
{
	static char *kwlist[] = { "extents", NULL };
	PyObject *py_extents;
	GValue v_extents = { 0, };
	DiaRectangle *extents;

	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:DiaCanvas.set_extents", kwlist, &py_extents))
		return NULL;

	g_value_init (&v_extents, DIA_TYPE_RECTANGLE);

	if (pyg_value_from_pyobject (&v_extents, py_extents))
		return NULL;

	extents = g_value_get_boxed (&v_extents);

	dia_canvas_set_extents(DIA_CANVAS(self->obj), extents);

	g_value_unset (&v_extents);

	Py_INCREF(Py_None);
	return Py_None;
}
%%
override dia_canvas_snap_to_grid kwargs
static PyObject *
_wrap_dia_canvas_snap_to_grid (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	static char *kwlist[] = { "x", "y", NULL };
	gdouble x, y;

	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				         "dd:DiaCanvas.snap_to_grid",
					 kwlist, &x, &y))
		return NULL;

	dia_canvas_snap_to_grid (DIA_CANVAS (self->obj), &x, &y);

	return Py_BuildValue ("(dd)", x, y);
}
%%
%%
override dia_canvas_find_objects_in_rectangle kwargs
static PyObject *
_wrap_dia_canvas_find_objects_in_rectangle (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	static char *kwlist[] = { "rect", NULL };
	PyObject *py_rect, *t;
	GValue value = { 0, };
	DiaRectangle *rect;
	GList *l, *tmp;
	int i;

	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				         "O:DiaCanvas.find_objects_in_rectangle",
					 kwlist, &py_rect))
		return NULL;

	g_value_init (&value, DIA_TYPE_RECTANGLE);

	if (pyg_value_from_pyobject (&value, py_rect))
		return NULL;

	rect = g_value_get_boxed (&value);

	l = dia_canvas_find_objects_in_rectangle (DIA_CANVAS (self->obj), rect);
	g_value_unset (&value);

	t = PyTuple_New(g_list_length (l));
	if (!t) {
		PyErr_SetString(PyExc_TypeError,
				"couldn't create dash tuple.");
		return NULL;
	}
	for (tmp = l, i = 0; tmp != NULL; tmp = tmp->next, i++) {
		// PyTuple_SetItem() steals the reference
		if (PyTuple_SetItem(t, i, pygobject_new (tmp->data)) != 0) {
			PyErr_SetString(PyExc_TypeError,
					"couldn't add a float to the tuple.");
			Py_DECREF (t);
			return NULL;
		}
	}
	g_list_free (l);
	return t;
}
%%
override dia_canvas_glue_handle kwargs
static PyObject *
_wrap_dia_canvas_glue_handle (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	static char *kwlist[] = { "handle", "dest_x", "dest_y", NULL };
	PyGObject *handle;
	gdouble dest_x, dest_y;
	gdouble dist, glue_x, glue_y;
	DiaCanvasItem *item;

	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
				         "O!dd:DiaCanvas.glue_handle",
					 kwlist, &PyDiaHandle_Type, &handle,
					 &dest_x, &dest_y))
		return NULL;

	dist = dia_canvas_glue_handle (DIA_CANVAS(self->obj),
				       DIA_HANDLE(handle->obj),
				       dest_x, dest_y,
				       &glue_x, &glue_y, &item);
	
	return Py_BuildValue ("(d(dd)N)", dist, glue_x, glue_y,
			      pygobject_new ((GObject*) item));
}
%%
override dia_canvas_item_create kwargs
static PyObject *
_wrap_dia_canvas_item_create (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	PyObject *pytype;
	PyObject *pygobject;
	GType type;
	DiaCanvasItem *item;
	GObjectClass *class;

	if (!PyArg_ParseTuple (args, "O:DiaCanvas.item_create", &pytype))
		return NULL;

	if ((type = pyg_type_from_object (pytype)) == 0)
		return NULL;

	item = dia_canvas_item_create (type, NULL);

	if (!item) {
		PyErr_SetString (PyExc_RuntimeError,
				 "could not create canvas item object");
		return NULL;
	}

	if (canvas_item_set_properties (item, kwargs) == -1)
		return NULL;

	g_message (__FUNCTION__": item ref %d", ((GObject *)item)->ref_count);
	return pygobject_new((GObject *) item);
}
%%
override dia_canvas_item_set kwargs
static PyObject*
_wrap_dia_canvas_item_set (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	DiaCanvasItem *item;

	item = DIA_CANVAS_ITEM (self->obj);

	canvas_item_set_properties (item, kwargs);

	Py_INCREF(Py_None);
	return Py_None;
}
%%
override dia_canvas_item_update_child kwargs
static PyObject*
_wrap_dia_canvas_item_update_child (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	static char *kwlist[] = { "child", "affine", NULL };
	PyObject *affine;
	PyGObject *child;
	GValue v = { 0, };

	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:DiaCanvasItem.update_child", kwlist, &PyDiaCanvasItem_Type, &child, &affine))
		return NULL;

	g_value_init (&v, DIA_TYPE_AFFINE);
	if (pyg_value_from_pyobject (&v, affine) != 0)
		return NULL;
    
	dia_canvas_item_update_child (DIA_CANVAS_ITEM(self->obj),
				      DIA_CANVAS_ITEM(child->obj),
				      g_value_get_boxed (&v));

	g_value_unset (&v);
	Py_INCREF (Py_None);
	return Py_None;
}
%%
override dia_canvas_item_affine_w2i noargs
static PyObject *
_wrap_dia_canvas_item_affine_w2i (PyGObject *self)
{
	double a[6];

	dia_canvas_item_affine_w2i (DIA_CANVAS_ITEM(self->obj), a);

	return Py_BuildValue("(dddddd)", a[0], a[1], a[2], a[3], a[4], a[5]);
}
%%
override dia_canvas_item_affine_i2w noargs
static PyObject *
_wrap_dia_canvas_item_affine_i2w (PyGObject *self)
{
	double a[6];

	dia_canvas_item_affine_i2w (DIA_CANVAS_ITEM(self->obj), a);

	return Py_BuildValue("(dddddd)", a[0], a[1], a[2], a[3], a[4], a[5]);
}
%%
override dia_canvas_item_affine_point_w2i kwargs
static PyObject *
_wrap_dia_canvas_item_affine_point_w2i (PyGObject *self, PyObject *args,
					PyObject *kwargs)
{
	static char *kwlist[] = { "x", "y", NULL };
	double x, y;

	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
					 "dd:DiaCanvasItem.affine_point_w2i",
					 kwlist, &x, &y))
		return NULL;
	dia_canvas_item_affine_point_w2i (DIA_CANVAS_ITEM(self->obj), &x, &y);

	return Py_BuildValue("(dd)", x, y);
}
%%
override dia_canvas_item_affine_point_i2w kwargs
static PyObject *
_wrap_dia_canvas_item_affine_point_i2w (PyGObject *self, PyObject *args,
					PyObject *kwargs)
{
	static char *kwlist[] = { "x", "y", NULL };
	double x, y;

	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
					 "dd:DiaCanvasItem.affine_point_i2w",
					 kwlist, &x, &y))
		return NULL;
	dia_canvas_item_affine_point_i2w (DIA_CANVAS_ITEM(self->obj), &x, &y);

	return Py_BuildValue("(dd)", x, y);
}
%%
override dia_canvas_item_shape_iter noargs
static PyObject *
_wrap_dia_canvas_item_shape_iter (PyGObject *self)
{
	PyObject *py_ret;

        py_ret = PyObject_CallMethod ((PyObject*) self, "on_shape_iter", "");
        if (!py_ret) {
                PyErr_Print();
                PyErr_Clear();
		Py_INCREF (Py_None);
		return Py_None;
        } else
                return py_ret;
}
%%
override-attr DiaCanvasItem.handles
static PyObject *
_wrap_dia_canvas_item__get_handles (PyGObject *self, void *closure)
{
	GList *l;
	PyObject *list;
	int i;

	l = DIA_CANVAS_ITEM (self->obj)->handles;
	list = PyList_New (g_list_length (l));

	for (i = 0 ; l != NULL; l = l->next) {
		// PyList_SetItem() steals the reference
		if (PyList_SetItem (list, i++, pygobject_new (l->data)) != 0) {
			PyErr_Print();
			PyErr_Clear();
			break;
		}
	}

	return list;
}
%%
override-attr DiaCanvasItem.affine
static PyObject *
_wrap_dia_canvas_item__get_affine (PyGObject *self, void *closure)
{
	gdouble *a = (gdouble*) &DIA_CANVAS_ITEM (self->obj)->affine;

	return Py_BuildValue("(dddddd)", a[0], a[1], a[2], a[3], a[4], a[5]);
}
%%
override-attr DiaCanvasItem.bounds
static PyObject *
_wrap_dia_canvas_item__get_bounds (PyGObject *self, void *closure)
{
	DiaRectangle *b = &DIA_CANVAS_ITEM (self->obj)->bounds;

	return Py_BuildValue("(dddd)", b->left, b->top, b->right, b->bottom);
}
%%
override dia_canvas_item_get_bounds kwargs
static PyObject *
_wrap_dia_canvas_item_get_bounds(PyGObject *self, PyObject *args, PyObject *kwargs)
{
	static char *kwlist[] = { "affine", NULL };
	PyObject *affine = NULL;
	gdouble x1, y1, x2, y2;

	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:DiaCanvasItem.get_bounds", kwlist, &affine))
		return NULL;

	if (affine) {
		GValue v = { 0, };
		g_value_init (&v, DIA_TYPE_AFFINE);
		if (pyg_value_from_pyobject (&v, affine) != 0)
			return NULL;
	    
		dia_canvas_item_bb_affine (DIA_CANVAS_ITEM(self->obj),
					   g_value_get_boxed (&v),
					   &x1, &y1, &x2, &y2);
		g_value_unset (&v);
	} else {
		DiaRectangle *b = &DIA_CANVAS_ITEM(self->obj)->bounds;
		x1 = b->left;
		y1 = b->top;
		x2 = b->right;
		y2 = b->bottom;
	}

	return Py_BuildValue ("(dddd)", x1, y1, x2, y2);
}
%%
override dia_canvas_item_set_bounds kwargs
static PyObject *
_wrap_dia_canvas_item_set_bounds(PyGObject *self, PyObject *args, PyObject *kwargs)
{
	static char *kwlist[] = { "bounds", NULL };
	PyObject *py_bounds;
	GValue v_bounds = { 0, };
	DiaRectangle *bounds;

	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:DiaCanvasItem.set_bounds", kwlist, &py_bounds))
		return NULL;

	g_value_init (&v_bounds, DIA_TYPE_RECTANGLE);

	if (pyg_value_from_pyobject (&v_bounds, py_bounds))
		return NULL;

	bounds = g_value_get_boxed (&v_bounds);

	DIA_CANVAS_ITEM(self->obj)->bounds = *bounds;

	g_value_unset (&v_bounds);

	Py_INCREF(Py_None);
	return Py_None;
}
%%
override dia_canvas_item_on_update kwargs
/*
 * from pydiacanvasitem.c:
 */
extern PyGObject* _wrap_dia_canvas_item_on_update (PyGObject *self, PyObject *args, PyObject* kwargs);
%%
override dia_canvas_item_on_shape_iter noargs
extern PyGObject* _wrap_dia_canvas_item_on_shape_iter (PyGObject *self);
%%
override dia_canvas_item_on_point kwargs
extern PyObject* _wrap_dia_canvas_item_on_point (PyGObject *self, PyObject *args, PyObject *kwargs);
%%
override dia_canvas_item_on_move kwargs
extern PyObject* _wrap_dia_canvas_item_on_move (PyGObject *self, PyObject *args, PyObject *kwargs);
%%
override dia_canvas_item_on_handle_motion kwargs
extern PyObject* _wrap_dia_canvas_item_on_handle_motion (PyGObject *self, PyObject *args, PyObject *kwargs);
%%
override dia_canvas_item_on_glue kwargs
extern PyObject* _wrap_dia_canvas_item_on_glue(PyGObject *self, PyObject *args, PyObject *kwargs);
%%
override dia_canvas_item_on_event kwargs
extern PyObject* _wrap_dia_canvas_item_on_event(PyGObject *self, PyObject *args, PyObject *kwargs);
%%
override dia_canvas_item_on_connect_handle kwargs
extern PyObject* _wrap_dia_canvas_item_on_connect_handle(PyGObject *self, PyObject *args, PyObject *kwargs);
%%
override dia_canvas_item_on_disconnect_handle kwargs
extern PyObject* _wrap_dia_canvas_item_on_disconnect_handle(PyGObject *self, PyObject *args, PyObject *kwargs);
%%
override dia_canvas_item_set_callbacks args

extern void pydia_canvas_item_class_init (DiaCanvasItemClass *klass);

static PyObject *
_wrap_dia_canvas_item_set_callbacks(PyGObject *self, PyObject *args)
{
	PyTypeObject *class;
	DiaCanvasItemClass *item_class;
	GType type;

	if (!PyArg_ParseTuple(args, "O:diacanvas.set_callbacks", &class))
		return NULL;
	if (!PyType_IsSubtype(class, &PyDiaCanvasItem_Type)) {
	    PyErr_SetString(PyExc_TypeError,"argument must be a DiaCanvasItem subclass");
		return NULL;
	}

	type = pyg_type_from_object ((PyObject*) class);
	item_class = g_type_class_ref (type);
	pydia_canvas_item_class_init (item_class);
	g_type_class_unref (item_class);

	Py_INCREF (Py_None);
	return Py_None;
}
%%
override dia_canvas_item_set_groupable args

extern void pydia_canvas_groupable_init (DiaCanvasGroupable *groupable);

static PyObject *
_wrap_dia_canvas_item_set_groupable(PyGObject *self, PyObject *args)
{
	static  const GInterfaceInfo groupable_info = {
		(GInterfaceInitFunc) pydia_canvas_groupable_init,
		NULL,
		NULL,
	};

	PyTypeObject *class;
	DiaCanvasItemClass *item_class;
	GType type;

	if (!PyArg_ParseTuple(args, "O:diacanvas.set_groupable", &class))
		return NULL;
	if (!PyType_IsSubtype(class, &PyDiaCanvasItem_Type)) {
	    PyErr_SetString(PyExc_TypeError,"argument must be a DiaCanvasItem subclass");
		return NULL;
	}

	type = pyg_type_from_object ((PyObject*) class);
	item_class = g_type_class_ref (type);
	if (g_type_interface_peek (item_class, DIA_TYPE_CANVAS_GROUPABLE)) {
		g_warning ("Trying to add DiaCanvasGroupable interface twice to the same class.");
	} else {
		g_type_add_interface_static (type,
					     DIA_TYPE_CANVAS_GROUPABLE,
					     &groupable_info);

		pydia_canvas_item_class_init (item_class);
	}
	g_type_class_unref (item_class);

	Py_INCREF (Py_None);
	return Py_None;
}
%%
override dia_canvas_item_set_editable args

extern void pydia_canvas_editable_init (DiaCanvasEditable *editable);

static PyObject *
_wrap_dia_canvas_item_set_editable(PyGObject *self, PyObject *args)
{
	static  const GInterfaceInfo editable_info = {
		(GInterfaceInitFunc) pydia_canvas_editable_init,
		NULL,
		NULL,
	};

	PyTypeObject *class;
	DiaCanvasItemClass *item_class;
	GType type;

	if (!PyArg_ParseTuple(args, "O:diacanvas.set_editable", &class))
		return NULL;
	if (!PyType_IsSubtype(class, &PyDiaCanvasItem_Type)) {
	    PyErr_SetString(PyExc_TypeError,"argument must be a DiaCanvasItem subclass");
		return NULL;
	}

	type = pyg_type_from_object ((PyObject*) class);
	item_class = g_type_class_ref (type);
	if (g_type_interface_peek (item_class, DIA_TYPE_CANVAS_EDITABLE)) {
		g_warning ("Trying to add DiaCanvasEditable interface twice to the same class.");
	} else {
		g_type_add_interface_static (type,
					     DIA_TYPE_CANVAS_EDITABLE,
					     &editable_info);

		pydia_canvas_item_class_init (item_class);
	}
	g_type_class_unref (item_class);

	Py_INCREF (Py_None);
	return Py_None;
}
%%
override dia_handle_get_pos_i noargs
static PyObject *
_wrap_dia_handle_get_pos_i (PyGObject *self)
{
	gdouble x, y;

	dia_handle_get_pos_i (DIA_HANDLE (self->obj), &x, &y);

	return Py_BuildValue ("(dd)", x, y);
}
%%
override dia_handle_get_pos_w noargs
static PyObject *
_wrap_dia_handle_get_pos_w (PyGObject *self)
{
	gdouble x, y;

	dia_handle_get_pos_w (DIA_HANDLE (self->obj), &x, &y);

	return Py_BuildValue ("(dd)", x, y);
}
%%
override-attr DiaHandle.x
static PyObject *
_wrap_dia_handle__get_x(PyObject *self, void *closure)
{
    DiaVariable *ret;

    ret = DIA_HANDLE(pygobject_get(self))->pos_i.x;
    /* pygobject_new handles NULL checking */
    return pygobject_new((GObject *)ret);
}
%%
override-attr DiaHandle.y
static PyObject *
_wrap_dia_handle__get_y(PyObject *self, void *closure)
{
    DiaVariable *ret;

    ret = DIA_HANDLE(pygobject_get(self))->pos_i.y;
    /* pygobject_new handles NULL checking */
    return pygobject_new((GObject *)ret);
}
%%
override-attr DiaHandle.wx
static PyObject *
_wrap_dia_handle__get_wx(PyObject *self, void *closure)
{
    DiaVariable *ret;

    ret = DIA_HANDLE(pygobject_get(self))->pos_w.x;
    /* pygobject_new handles NULL checking */
    return pygobject_new((GObject *)ret);
}
%%
override-attr DiaHandle.wy
static PyObject *
_wrap_dia_handle__get_wy(PyObject *self, void *closure)
{
    DiaVariable *ret;

    ret = DIA_HANDLE(pygobject_get(self))->pos_w.y;
    /* pygobject_new handles NULL checking */
    return pygobject_new((GObject *)ret);
}
%%
override dia_canvas_group_create_item kwargs
static PyObject *
_wrap_dia_canvas_group_create_item (PyGObject *self, PyObject *args, PyObject *kwargs)
{
	PyObject *pytype;
	PyObject *pygobject;
	GType type;
	DiaCanvasItem *item;

	if (!PyArg_ParseTuple (args, "O:DiaCanvasGroup.create_item", &pytype))
		return NULL;

	if ((type = pyg_type_from_object(pytype)) == 0)
		return NULL;

	item = dia_canvas_group_create_item (DIA_CANVAS_GROUP (self->obj),
					     type, NULL);

	if (!item) {
		PyErr_SetString (PyExc_RuntimeError,
				 "could not create canvas item object");
		return NULL;
	}

	if (canvas_item_set_properties (item, kwargs) == -1)
		return NULL;

	/* dia_canvas_group_create_item() does return a borrowed reference.
	 * So we have to increment our refcount. */
	g_object_ref (item);
	return pygobject_new((GObject *) item);
}
%%
override-attr DiaCanvasGroup.children
static PyObject *
_wrap_dia_canvas_group__get_children (PyGObject *self, void *closure)
{
	GList *l;
	PyObject *list;
	int i;

	l = DIA_CANVAS_GROUP(self->obj)->children;
	list = PyList_New (g_list_length (l));

	for (i = 0 ; l != NULL; l = l->next) {
		// PyList_SetItem steals the reference
		if (PyList_SetItem (list, i++, pygobject_new (l->data)) != 0) {
			PyErr_Print();
			PyErr_Clear();
			break;
		}
	}

	return list;
}
%%
override dia_canvas_groupable_iter noargs
static PyObject *
_wrap_dia_canvas_groupable_iter (PyGObject *self)
{
	PyObject *py_ret;

        py_ret = PyObject_CallMethod ((PyObject*) self, "on_groupable_iter", "");
        if (!py_ret) {
                PyErr_Print();
                PyErr_Clear();
		Py_INCREF (Py_None);
		return Py_None;
        } else
                return py_ret;
}
%%
override-slot DiaEvent.tp_getattr
PyObject *
_wrap_dia_event_tp_getattr(PyObject *self, char *attr)
{
	DiaEvent *event = pyg_boxed_get(self, DiaEvent);

	if (!strcmp(attr, "type"))
		return PyInt_FromLong(event->type);

	switch(event->type) {
	case DIA_EVENT_MOTION:
		if (!strcmp(attr, "x"))
			return PyFloat_FromDouble(event->motion.x);
		if (!strcmp(attr, "y"))
			return PyFloat_FromDouble(event->motion.y);
		if (!strcmp(attr, "modifier"))
			return PyInt_FromLong(event->motion.modifier);
		if (!strcmp(attr, "dx"))
			return PyFloat_FromDouble(event->motion.dx);
		if (!strcmp(attr, "dy"))
			return PyFloat_FromDouble(event->motion.dy);
		break;

	case DIA_EVENT_BUTTON_PRESS:
	case DIA_EVENT_2BUTTON_PRESS:
	case DIA_EVENT_3BUTTON_PRESS:
	case DIA_EVENT_BUTTON_RELEASE:
		if (!strcmp(attr, "x"))
			return PyFloat_FromDouble(event->button.x);
		if (!strcmp(attr, "y"))
			return PyFloat_FromDouble(event->button.y);
		if (!strcmp(attr, "modifier"))
			return PyInt_FromLong(event->button.modifier);
		if (!strcmp(attr, "button"))
			return PyInt_FromLong(event->button.button);
		break;
	case DIA_EVENT_KEY_PRESS:
	case DIA_EVENT_KEY_RELEASE:
		if (!strcmp(attr, "modifier"))
			return PyInt_FromLong(event->key.modifier);
		if (!strcmp(attr, "keyval"))
			return PyInt_FromLong(event->key.keyval);
		if (!strcmp(attr, "string"))
			return PyString_FromStringAndSize(event->key.string,
							  event->key.length);
		break;
	default:
		break;
	}
	PyErr_SetString(PyExc_AttributeError, attr);
	return NULL;
}
%%
override-attr DiaCanvasText.text
static PyObject *
_wrap_dia_canvas_text__get_text(PyObject *self, void *closure)
{
    GString *ret;

    ret = DIA_CANVAS_TEXT(pygobject_get(self))->text;
    if (ret && ret->str)
        return PyString_FromString(ret->str);
    Py_INCREF(Py_None);
    return Py_None;
}
