[dia] PyDia: some more reflection support
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] PyDia: some more reflection support
- Date: Sat, 30 Jul 2011 12:16:47 +0000 (UTC)
commit b58dba38c702abd84693311d1421e46c959d7bf1
Author: Hans Breuer <hans breuer org>
Date: Tue Jul 26 21:26:55 2011 +0200
PyDia: some more reflection support
Define the return value of Object.get_object_menu() to allow
some more reflection, i.e. checking for object specific menu
items. Also expose some more information of properties.
plug-ins/python/Makefile.am | 2 +
plug-ins/python/diamodule.c | 4 +
plug-ins/python/makefile.msc | 1 +
plug-ins/python/pydia-error.c | 16 +++-
plug-ins/python/pydia-menuitem.c | 181 ++++++++++++++++++++++++++++++++++++++
plug-ins/python/pydia-menuitem.h | 17 ++++
plug-ins/python/pydia-object.c | 32 +++++++
plug-ins/python/pydia-property.c | 6 +-
8 files changed, 256 insertions(+), 3 deletions(-)
---
diff --git a/plug-ins/python/Makefile.am b/plug-ins/python/Makefile.am
index 96e54c1..6c38acc 100644
--- a/plug-ins/python/Makefile.am
+++ b/plug-ins/python/Makefile.am
@@ -41,6 +41,8 @@ libpython_plugin_la_SOURCES = \
pydia-image.h \
pydia-layer.c \
pydia-layer.h \
+ pydia-menuitem.c \
+ pydia-menuitem.h \
pydia-object.c \
pydia-object.h \
pydia-paperinfo.c \
diff --git a/plug-ins/python/diamodule.c b/plug-ins/python/diamodule.c
index 491ff8d..01a0b2e 100644
--- a/plug-ins/python/diamodule.c
+++ b/plug-ins/python/diamodule.c
@@ -38,6 +38,7 @@
#include "pydia-error.h"
#include "pydia-text.h"
#include "pydia-paperinfo.h"
+#include "pydia-menuitem.h"
#include "lib/dialib.h"
#include "lib/object.h"
@@ -578,6 +579,7 @@ initdia(void)
PyDiaMatrix_Type.ob_type = &PyType_Type;
PyDiaText_Type.ob_type = &PyType_Type;
PyDiaPaperinfo_Type.ob_type = &PyType_Type;
+ PyDiaMenuitem_Type.ob_type = &PyType_Type;
#endif
m = Py_InitModule3("dia", dia_methods, dia_module_doc);
@@ -637,6 +639,8 @@ initdia(void)
(void *)&PyDiaText_Type);
PyDict_SetItemString(d, "Paperinfo",
(void *)&PyDiaPaperinfo_Type);
+ PyDict_SetItemString(d, "Menuitem",
+ (void *)&PyDiaMenuitem_Type);
if (PyErr_Occurred())
Py_FatalError("can't initialise module dia");
diff --git a/plug-ins/python/makefile.msc b/plug-ins/python/makefile.msc
index a76ef50..8612e1c 100644
--- a/plug-ins/python/makefile.msc
+++ b/plug-ins/python/makefile.msc
@@ -35,6 +35,7 @@ OBJECTS = \
pydia-handle.obj \
pydia-image.obj \
pydia-layer.obj \
+ pydia-menuitem.obj \
pydia-object.obj \
pydia-paperinfo.obj \
pydia-properties.obj \
diff --git a/plug-ins/python/pydia-error.c b/plug-ins/python/pydia-error.c
index 52654a0..bef2447 100644
--- a/plug-ins/python/pydia-error.c
+++ b/plug-ins/python/pydia-error.c
@@ -177,6 +177,18 @@ PyTypeObject PyDiaError_Type = {
(hashfunc)PyDiaError_Hash,
(ternaryfunc)0,
(reprfunc)PyDiaError_Str,
- 0L,0L,0L,0L,
- NULL
+ (getattrofunc)0L,
+ (setattrofunc)0L,
+ (PyBufferProcs *)0L,
+ 0L, /* Flags */
+ "The error object is just a helper to redirect errors to messages",
+ (traverseproc)0,
+ (inquiry)0,
+ (richcmpfunc)0,
+ 0, /* tp_weakliszoffset */
+ (getiterfunc)0,
+ (iternextfunc)0,
+ PyDiaError_Methods, /* tp_methods */
+ NULL, /* tp_members */
+ 0
};
diff --git a/plug-ins/python/pydia-menuitem.c b/plug-ins/python/pydia-menuitem.c
new file mode 100644
index 0000000..31b0b04
--- /dev/null
+++ b/plug-ins/python/pydia-menuitem.c
@@ -0,0 +1,181 @@
+/* Python plug-in for dia
+ * Copyright (C) 1999 James Henstridge
+ * Copyright (C) 2011 Hans Breuer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#include "pydia-menuitem.h"
+#include "pydia-object.h" /* for PyObject_HEAD_INIT */
+
+#include <structmember.h> /* PyMemberDef */
+
+/*
+ * New
+ */
+PyObject* PyDiaMenuitem_New (const DiaMenuItem *menuitem)
+{
+ PyDiaMenuitem *self;
+
+ self = PyObject_NEW(PyDiaMenuitem, &PyDiaMenuitem_Type);
+ if (!self) return NULL;
+
+ self->menuitem = menuitem;
+
+ return (PyObject *)self;
+}
+
+/*
+ * Dealloc
+ */
+static void
+PyDiaMenuitem_Dealloc(PyDiaMenuitem *self)
+{
+ /* we dont own the object */
+ PyObject_DEL(self);
+}
+
+/*
+ * Compare
+ */
+static int
+PyDiaMenuitem_Compare(PyDiaMenuitem *self,
+ PyDiaMenuitem *other)
+{
+ return (self->menuitem == other->menuitem);
+}
+
+/*
+ * Hash
+ */
+static long
+PyDiaMenuitem_Hash(PyObject *self)
+{
+ return (long)self;
+}
+
+/*
+ * GetAttr
+ */
+static PyObject *
+PyDiaMenuitem_GetAttr(PyDiaMenuitem *self, gchar *attr)
+{
+ if (!strcmp(attr, "__members__"))
+ return Py_BuildValue("[ss]", "text", "active");
+ else if (!strcmp(attr, "text"))
+ return PyString_FromString(self->menuitem->text);
+ else if (!strcmp(attr, "active"))
+ return PyInt_FromLong(self->menuitem->active);
+
+ PyErr_SetString(PyExc_AttributeError, attr);
+ return NULL;
+}
+
+
+static PyObject *
+PyDiaMenuitem_Call(PyDiaMenuitem *self, PyObject *args)
+{
+ const DiaMenuItem *mi;
+ ObjectChange *oc;
+ DiaObject *obj;
+ Point clicked;
+
+ if (!PyArg_ParseTuple(args, "O!(dd)|ii:Menuitem.callback",
+ &PyDiaObject_Type, &obj, &clicked.x, &clicked.y))
+ return NULL;
+
+ mi = self->menuitem;
+
+ oc = mi->callback (obj, &clicked, mi->callback_data);
+ /* Throw away the undo information */
+ if (oc) {
+ if (oc->free)
+ oc->free(oc);
+ g_free (oc);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+/*
+ * Repr / _Str
+ */
+static PyObject *
+PyDiaMenuitem_Str(PyDiaMenuitem *self)
+{
+ PyObject* py_s;
+ gchar* s = g_strdup_printf("%s - %s,%s,%s",
+ self->menuitem->text,
+ self->menuitem->active & DIAMENU_ACTIVE ? "active" : "inactive",
+ self->menuitem->active & DIAMENU_TOGGLE ? "toggle" : "",
+ self->menuitem->active & DIAMENU_TOGGLE_ON ? "on" : "");
+ py_s = PyString_FromString(s);
+ g_free (s);
+ return py_s;
+}
+
+static PyMethodDef PyDiaMenuitem_Methods[] = {
+ { "call", (PyCFunction)PyDiaMenuitem_Call, METH_VARARGS,
+ "call() -> None."
+ " Invoke the menuitem callback on object." },
+ { NULL, 0, 0, NULL }
+};
+
+#define T_INVALID -1 /* can't allow direct access due to pyobject->menuitem indirection */
+static PyMemberDef PyDiaMenuitem_Members[] = {
+ { "text", T_INVALID, 0, RESTRICTED|READONLY,
+ "string: what would be written in the menu" },
+ { "active", T_INVALID, 0, RESTRICTED|READONLY,
+ "boolean: if it is callable" },
+ { NULL }
+};
+/*
+ * Python objetcs
+ */
+PyTypeObject PyDiaMenuitem_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "dia.Menuitem",
+ sizeof(PyDiaMenuitem),
+ 0,
+ (destructor)PyDiaMenuitem_Dealloc,
+ (printfunc)0,
+ (getattrfunc)PyDiaMenuitem_GetAttr,
+ (setattrfunc)0,
+ (cmpfunc)PyDiaMenuitem_Compare,
+ (reprfunc)0,
+ 0,
+ 0,
+ 0,
+ (hashfunc)PyDiaMenuitem_Hash,
+ (ternaryfunc)0,
+ (reprfunc)PyDiaMenuitem_Str,
+ (getattrofunc)0,
+ (setattrofunc)0,
+ (PyBufferProcs *)0,
+ 0L, /* Flags */
+ "dia.Menuitem is holding menu functions for dia.Object",
+ (traverseproc)0,
+ (inquiry)0,
+ (richcmpfunc)0,
+ 0, /* tp_weakliszoffset */
+ (getiterfunc)0,
+ (iternextfunc)0,
+ PyDiaMenuitem_Methods, /* tp_methods */
+ PyDiaMenuitem_Members, /* tp_members */
+ 0
+};
diff --git a/plug-ins/python/pydia-menuitem.h b/plug-ins/python/pydia-menuitem.h
new file mode 100644
index 0000000..56e8122
--- /dev/null
+++ b/plug-ins/python/pydia-menuitem.h
@@ -0,0 +1,17 @@
+#ifndef PYDIA_MENUITEM_H
+#define PYDIA_MENUITEM_H
+
+#include <Python.h>
+#include "object.h"
+
+typedef struct {
+ PyObject_HEAD
+ const DiaMenuItem *menuitem;
+} PyDiaMenuitem;
+
+
+extern PyTypeObject PyDiaMenuitem_Type;
+
+PyObject *PyDiaMenuitem_New(const DiaMenuItem *layer);
+
+#endif /* PYDIA_MENUITEM_H */
diff --git a/plug-ins/python/pydia-object.c b/plug-ins/python/pydia-object.c
index d9d289e..afceb6e 100644
--- a/plug-ins/python/pydia-object.c
+++ b/plug-ins/python/pydia-object.c
@@ -25,6 +25,7 @@
#include "pydia-geometry.h"
#include "pydia-properties.h"
#include "pydia-render.h"
+#include "pydia-menuitem.h"
#include <structmember.h> /* PyMemberDef */
@@ -157,6 +158,35 @@ PyDiaObject_Copy(PyDiaObject *self, PyObject *args)
}
static PyObject *
+PyDiaObject_GetMenu(PyDiaObject *self, PyObject *args)
+{
+ PyObject *ret, *items;
+ Point clicked = { 0, 0 };
+ DiaMenu *m;
+ int i;
+
+
+ if (!PyArg_ParseTuple(args, ":Object.get_object_menu"))
+ return NULL;
+
+ if (!self->object->ops->get_object_menu ||
+ !(m = self->object->ops->get_object_menu (self->object, &clicked))) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ } ;
+
+ ret = PyTuple_New (2);
+ PyTuple_SetItem(ret, 0, PyString_FromString (m->title ? m->title : ""));
+ items = PyList_New(0);
+ for (i = 0; i < m->num_items; ++i) {
+ DiaMenuItem *mi = &m->items[i];
+ if (mi->text && mi->callback)
+ PyList_Append(items, PyDiaMenuitem_New (mi));
+ }
+ PyTuple_SetItem(ret, 1, items);
+ return ret;
+}
+static PyObject *
PyDiaObject_Move(PyDiaObject *self, PyObject *args)
{
Point point;
@@ -219,6 +249,8 @@ static PyMethodDef PyDiaObject_Methods[] = {
{ "draw", (PyCFunction)PyDiaObject_Draw, METH_VARARGS,
"draw(dia.Renderer: r) -> None."
" Draw the object with the given renderer" },
+ { "get_object_menu", (PyCFunction)PyDiaObject_GetMenu, METH_VARARGS,
+ "get_object_menu() -> Tuple. Returns a named list of Menuitem(s)." },
{ "move", (PyCFunction)PyDiaObject_Move, METH_VARARGS,
"move(real: x, real: y) -> None."
" Move the entire object. The given point is the new object.obj_pos." },
diff --git a/plug-ins/python/pydia-property.c b/plug-ins/python/pydia-property.c
index 009b643..04efbe4 100644
--- a/plug-ins/python/pydia-property.c
+++ b/plug-ins/python/pydia-property.c
@@ -805,11 +805,15 @@ PyDiaProperty_GetAttr(PyDiaProperty *self, gchar *attr)
{
if (!strcmp(attr, "__members__"))
- return Py_BuildValue("[ssss]", "name", "type", "value", "visible");
+ return Py_BuildValue("[ssss]", "name", "type", "value", "visible", "description", "tooltip");
else if (!strcmp(attr, "name"))
return PyString_FromString(self->property->descr->name);
else if (!strcmp(attr, "type"))
return PyString_FromString(self->property->descr->type);
+ else if (!strcmp(attr, "description"))
+ return PyString_FromString(self->property->descr->description);
+ else if (!strcmp(attr, "tooltip"))
+ return PyString_FromString(self->property->descr->tooltip);
else if (!strcmp(attr, "visible"))
return PyInt_FromLong(0 != (self->property->descr->flags & PROP_FLAG_VISIBLE));
else if (!strcmp(attr, "value")) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]