diff options
author | James Henstridge <james@daa.com.au> | 1999-08-02 15:33:30 +0000 |
---|---|---|
committer | James Henstridge <jamesh@src.gnome.org> | 1999-08-02 15:33:30 +0000 |
commit | f50c95a9ec48b77673437e21fabc9f5ab79861b0 (patch) | |
tree | 535cba678c9cc54de2c1b15d9894354151f00ece | |
parent | c4c2be444a5ed80bd15be678e522bfa6600aeacb (diff) | |
download | pygtk-f50c95a9ec48b77673437e21fabc9f5ab79861b0.tar.gz |
new file that wraps the _libglade module.
1999-08-02 James Henstridge <james@daa.com.au>
* libglade.py: new file that wraps the _libglade module.
* libglademodule.c: handle connecting to another object correctly.
* gtkmodule.c: added support for passing an object for
gtk_signal_connect_object type behaviour.
(_wrap_gtk_signal_connect_object)
(_wrap_gtk_signal_connect_object_after): new wrappers.
* gtk.py (idle_add, timeout_add, quit_add): pass extra arguments to
the callback.
* libglademodule.c (_wrap_glade_xml_signal_connect): fixed a small
problem with reference counting here.
* gtkmodule.c: added support for passing arguments to timeout, quit
and idle functions.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | generate/libglade.defs | 6 | ||||
-rw-r--r-- | gtk.py | 12 | ||||
-rw-r--r-- | gtkmodule.c | 174 | ||||
-rw-r--r-- | libglade.py | 61 | ||||
-rw-r--r-- | libglademodule.c | 38 |
7 files changed, 234 insertions, 68 deletions
@@ -1,5 +1,14 @@ 1999-08-02 James Henstridge <james@daa.com.au> + * libglade.py: new file that wraps the _libglade module. + + * libglademodule.c: handle connecting to another object correctly. + + * gtkmodule.c: added support for passing an object for + gtk_signal_connect_object type behaviour. + (_wrap_gtk_signal_connect_object) + (_wrap_gtk_signal_connect_object_after): new wrappers. + * gtk.py (idle_add, timeout_add, quit_add): pass extra arguments to the callback. diff --git a/Makefile.am b/Makefile.am index 271f0bbf..653ae61c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,7 +19,7 @@ gtkgl_mods = endif if BUILD_LIBGLADE libglade_libs = _libglademodule$(SO) -libglade_mods = +libglade_mods = libglade.py else libglade_libs = libglade_mods = diff --git a/generate/libglade.defs b/generate/libglade.defs index 65178db5..c3377110 100644 --- a/generate/libglade.defs +++ b/generate/libglade.defs @@ -5,13 +5,13 @@ (define-func glade_xml_new GladeXML ((string filename) - (string rooot))) + (string rooot (null-ok)))) (define-func glade_xml_new_with_domain GladeXML ((string filename) - (string root) - (string domain))) + (string root (null-ok)) + (string domain (null-ok)))) ; glade_xml_signal_connect_full ; glade_xml_signal_autoconnect_full @@ -132,6 +132,18 @@ class GtkObject: return _gtk.gtk_signal_connect_after(self._o, name, callback.__call__, extra) signal_connect_after = connect_after + def connect_object(self, name, f, obj, *extra): + callback = self.__cnv(f) + return _gtk.gtk_signal_connect_object(self._o, name, + callback.__call__, + obj._o, extra) + signal_connect_object = connect_object + def connect_object_after(self, name, f, obj, *extra): + callback = self.__cnv(f) + return _gtk.gtk_signal_connect_object_after(self._o, name, + callback.__call__, + obj._o, extra) + signal_connect_after = connect_after def disconnect(self, id): _gtk.gtk_signal_disconnect(self._o, id) def signal_handler_block(self, id): diff --git a/gtkmodule.c b/gtkmodule.c index 0b818a9d..02dbcce7 100644 --- a/gtkmodule.c +++ b/gtkmodule.c @@ -2755,49 +2755,57 @@ static int GtkArgs_FromSequence(GtkArg *args, int nparams, PyObject *seq) { /* generic callback marshal */ static void PyGtk_CallbackMarshal(GtkObject *o, gpointer data, guint nargs, GtkArg *args) { - PyObject *func = data, *ret, *a, *params; + PyObject *tuple = data, *func, *extra=NULL, *obj=NULL, *ret, *a, *params; - PyGTK_BLOCK_THREADS - a = GtkArgs_AsTuple(nargs, args); - if (a == NULL) { - PyErr_Clear(); - fprintf(stderr, "can't decode params -- callback not run\n"); - PyGTK_UNBLOCK_THREADS - return; - } - if (o == NULL) - params = a; - else { - /* prepend object to argument list */ - ret = PyTuple_New(1); - PyTuple_SetItem(ret, 0, PyGtk_New(o)); - params = PySequence_Concat(ret, a); - Py_DECREF(ret); Py_DECREF(a); - } - if (PyTuple_Check(func)) { - a = PyTuple_GetItem(func, 1); - func = PyTuple_GetItem(func, 0); - if (PyTuple_Check(a)) { - ret = params; - params = PySequence_Concat(ret, a); - Py_DECREF(ret); + PyGTK_BLOCK_THREADS + a = GtkArgs_AsTuple(nargs, args); + if (a == NULL) { + PyErr_Clear(); + fprintf(stderr, "can't decode params -- callback not run\n"); + PyGTK_UNBLOCK_THREADS + return; } - } - ret = PyObject_CallObject(func, params); - Py_DECREF(params); - if (ret == NULL) { - if (PyGtk_FatalExceptions) - gtk_main_quit(); - else { - PyErr_Print(); - PyErr_Clear(); + + if (PyTuple_Check(tuple)) { + func = PyTuple_GetItem(tuple, 0); + extra = PyTuple_GetItem(tuple, 1); + if (PyTuple_Size(tuple) > 2) { + obj = PyTuple_GetItem(tuple, 2); + Py_INCREF(obj); + } + } else + func = tuple; + if (!obj && o != NULL) + obj = PyGtk_New(o); + + if (obj) { + tuple = PyTuple_New(1); + PyTuple_SetItem(tuple, 0, obj); + params = PySequence_Concat(tuple, a); + Py_DECREF(tuple); Py_DECREF(a); + } else + params = a; + + if (extra) { + tuple = params; + params = PySequence_Concat(tuple, extra); + Py_DECREF(tuple); + } + ret = PyObject_CallObject(func, params); + Py_DECREF(params); + if (ret == NULL) { + if (PyGtk_FatalExceptions) + gtk_main_quit(); + else { + PyErr_Print(); + PyErr_Clear(); + } + PyGTK_UNBLOCK_THREADS + return; } + GtkRet_FromPyObject(&args[nargs], ret); + Py_DECREF(ret); PyGTK_UNBLOCK_THREADS - return; - } - GtkRet_FromPyObject(&args[nargs], ret); - Py_DECREF(ret); - PyGTK_UNBLOCK_THREADS } @@ -3019,7 +3027,7 @@ static GtkArg *PyDict_AsContainerArgs(PyObject *dict,GtkType type,gint *nargs){ static PyObject *_wrap_gtk_signal_connect(PyObject *self, PyObject *args) { PyGtk_Object *obj; char *name; - PyObject *func, *extra = NULL; + PyObject *func, *extra = NULL, *data; int signum; if (!PyArg_ParseTuple(args, "O!sO|O!:gtk_signal_connect", &PyGtk_Type, @@ -3030,24 +3038,21 @@ static PyObject *_wrap_gtk_signal_connect(PyObject *self, PyObject *args) { return NULL; } Py_INCREF(func); - if (extra) { - PyObject *tmp; - tmp = PyTuple_New(2); - PyTuple_SetItem(tmp, 0, func); - Py_INCREF(extra); - PyTuple_SetItem(tmp, 1, extra); - func = tmp; - } + if (extra) + Py_INCREF(extra); + else + extra = PyTuple_New(0); + data = Py_BuildValue("(OO)", func, extra); signum = gtk_signal_connect_full(PyGtk_Get(obj), name, NULL, (GtkCallbackMarshal)PyGtk_CallbackMarshal, - func, PyGtk_DestroyNotify, FALSE, FALSE); + data, PyGtk_DestroyNotify, FALSE, FALSE); return PyInt_FromLong(signum); } static PyObject *_wrap_gtk_signal_connect_after(PyObject *self, PyObject *args) { PyGtk_Object *obj; char *name; - PyObject *func, *extra = NULL; + PyObject *func, *extra = NULL, *data; int signum; if (!PyArg_ParseTuple(args, "O!sO|O!:gtk_signal_connect_after", @@ -3058,17 +3063,68 @@ static PyObject *_wrap_gtk_signal_connect_after(PyObject *self, PyObject *args) return NULL; } Py_INCREF(func); - if (extra) { - PyObject *tmp; - tmp = PyTuple_New(2); - PyTuple_SetItem(tmp, 0, func); - Py_INCREF(extra); - PyTuple_SetItem(tmp, 1, extra); - func = tmp; + if (extra) + Py_INCREF(extra); + else + extra = PyTuple_New(0); + data = Py_BuildValue("(OO)", func, extra); + signum = gtk_signal_connect_full(PyGtk_Get(obj), name, NULL, + (GtkCallbackMarshal)PyGtk_CallbackMarshal, + data, PyGtk_DestroyNotify, FALSE, TRUE); + return PyInt_FromLong(signum); +} + +static PyObject *_wrap_gtk_signal_connect_object(PyObject *self, PyObject *args) { + PyGtk_Object *obj; + char *name; + PyObject *func, *extra = NULL, *other, *data; + int signum; + + if (!PyArg_ParseTuple(args, "O!sOO!|O!:gtk_signal_connect_object", + &PyGtk_Type, &obj, &name, &func, &PyGtk_Type, &other, + &PyTuple_Type, &extra)) + return NULL; + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, "third argument must be callable"); + return NULL; } + Py_INCREF(func); + if (extra) + Py_INCREF(extra); + else + extra = PyTuple_New(0); + Py_INCREF(other); + data = Py_BuildValue("(OOO)", func, extra, other); + signum = gtk_signal_connect_full(PyGtk_Get(obj), name, NULL, + (GtkCallbackMarshal)PyGtk_CallbackMarshal, + data, PyGtk_DestroyNotify, FALSE, FALSE); + return PyInt_FromLong(signum); +} + +static PyObject *_wrap_gtk_signal_connect_object_after(PyObject *self, PyObject *args) { + PyGtk_Object *obj; + char *name; + PyObject *func, *extra = NULL, *other, *data; + int signum; + + if (!PyArg_ParseTuple(args, "O!sOO!|O!:gtk_signal_connect_object_after", + &PyGtk_Type, &obj, &name, &func, &PyGtk_Type, &other, + &PyTuple_Type, &extra)) + return NULL; + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, "third argument must be callable"); + return NULL; + } + Py_INCREF(func); + if (extra) + Py_INCREF(extra); + else + extra = PyTuple_New(0); + Py_INCREF(other); + data = Py_BuildValue("(OOO)", func, extra, other); signum = gtk_signal_connect_full(PyGtk_Get(obj), name, NULL, (GtkCallbackMarshal)PyGtk_CallbackMarshal, - func, PyGtk_DestroyNotify, FALSE, TRUE); + data, PyGtk_DestroyNotify, FALSE, TRUE); return PyInt_FromLong(signum); } @@ -5572,6 +5628,8 @@ static PyObject *_wrap_gdk_threads_leave(PyObject *self, PyObject *args) { static PyMethodDef _gtkmoduleMethods[] = { { "gtk_signal_connect", _wrap_gtk_signal_connect, 1 }, { "gtk_signal_connect_after", _wrap_gtk_signal_connect_after, 1 }, + { "gtk_signal_connect_object", _wrap_gtk_signal_connect_object, 1 }, + { "gtk_signal_connect_object_after", _wrap_gtk_signal_connect_object_after, 1 }, { "gtk_signal_disconnect_by_data", _wrap_gtk_signal_disconnect_by_data, 1 }, { "gtk_signal_handler_block_by_data", _wrap_gtk_signal_handler_block_by_data, 1 }, { "gtk_signal_handler_unblock_by_data", _wrap_gtk_signal_handler_unblock_by_data, 1 }, diff --git a/libglade.py b/libglade.py new file mode 100644 index 00000000..4fbdc630 --- /dev/null +++ b/libglade.py @@ -0,0 +1,61 @@ + +import gtk; _gtk = gtk; del gtk +import _libglade + +class GladeXML(_gtk.GtkData): + def __init__(self, filename=None, root=None, domain=None, _obj=None): + if _obj: self._o = _obj; return + self._o = _libglade.glade_xml_new_with_domain(filename, root, + domain) + class __cnv: + def __init__(self, func): + self.func = func + def __call__(self, *args): + a = list(args) + for i in range(len(args)): + if type(args[i]) == _gtk._gtk.GtkObjectType: + a[i] = _gtk._obj2inst(args[i]) + elif type(args[i]) == \ + _gtk._gtk.GtkAccelGroupType: + a[i] = _gtk.GtkAccelGroup(_obj=args[i]) + a = tuple(a) + ret = apply(self.func, a) + if hasattr(ret, '_o'): ret = ret._o + elif hasattr(ret, '_ag'): ret = ret._ag + elif hasattr(ret, '_im'): ret = ret._im + return ret + def signal_connect(self, handler_name, handler, *args): + _libglade.glade_xml_signal_connect(self._o, handler_name, + self.__cnv(handler).__call__, + args) + def signal_autoconnect(self, dict): + hdict = {} + for key, value in dict.items(): + if type(value) == type(()) and len(value) >= 2: + hdict[key] = (self.__cnv(value[0]).__call__, + value[1]) + else: + hdict[key] = self.__cnv(value).__call__ + _libglade.glade_xml_signal_autoconnect(self._o, hdict) + def get_widget(self, name): + wid = _libglade.glade_xml_get_widget(self._o, name) + if wid: + return _gtk._obj2inst(wid) + else: + return wid + def get_widget_by_longname(self, longname): + wid = _libglade.glade_xml_get_widget_by_long_name(self._o, + longname) + if wid: + return _gtk._obj2inst(wid) + else: + return wid +_gtk._name2cls['GladeXML'] = GladeXML + +def get_widget_name(widget): + return _libglade.glade_get_widget_name(widget._o) +def get_widget_long_name(widget): + return _libglade.glade_get_widget_long_name(widget._o) +def get_widget_tree(widget): + return GladeXML(_obj=_libglade.glade_get_widget_tree(widget._o)) + diff --git a/libglademodule.c b/libglademodule.c index 00509dd4..f461048c 100644 --- a/libglademodule.c +++ b/libglademodule.c @@ -32,9 +32,22 @@ static void connect_one(const gchar *handler_name, GtkObject *obj, gpointer user_data) { PyObject *callback = user_data; - if (connect_object) - g_warning("connect object not supported -- doing normal connect"); - Py_INCREF(callback); + if (connect_object) { + PyObject *func, *extra, *other; + + other = PyGtk_New(connect_object); + if (PyTuple_Check(callback)) { + func = PyTuple_GetItem(callback, 0); + extra = PyTuple_GetItem(callback, 1); + Py_INCREF(func); + Py_INCREF(extra); + callback = Py_BuildValue("(OOO)", func, extra, other); + } else { + Py_INCREF(callback); + callback = Py_BuildValue("(O()O)", callback, other); + } + } else + Py_INCREF(callback); gtk_signal_connect_full(obj, signal_name, NULL, (GtkCallbackMarshal)PyGtk_CallbackMarshal, @@ -56,9 +69,22 @@ static void connect_many(const gchar *handler_name, GtkObject *obj, if (!PyCallable_Check(callback)) return; - if (connect_object) - g_warning("connect object not supported -- doing normal connect"); - Py_INCREF(callback); + if (connect_object) { + PyObject *func, *extra, *other; + + other = PyGtk_New(connect_object); + if (PyTuple_Check(callback)) { + func = PyTuple_GetItem(callback, 0); + extra = PyTuple_GetItem(callback, 1); + Py_INCREF(func); + Py_INCREF(extra); + callback = Py_BuildValue("(OOO)", func, extra, other); + } else { + Py_INCREF(callback); + callback = Py_BuildValue("(O()O)", callback, other); + } + } else + Py_INCREF(callback); gtk_signal_connect_full(obj, signal_name, NULL, (GtkCallbackMarshal)PyGtk_CallbackMarshal, |