summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Henstridge <james@daa.com.au>1999-08-02 15:33:30 +0000
committerJames Henstridge <jamesh@src.gnome.org>1999-08-02 15:33:30 +0000
commitf50c95a9ec48b77673437e21fabc9f5ab79861b0 (patch)
tree535cba678c9cc54de2c1b15d9894354151f00ece
parentc4c2be444a5ed80bd15be678e522bfa6600aeacb (diff)
downloadpygtk-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--ChangeLog9
-rw-r--r--Makefile.am2
-rw-r--r--generate/libglade.defs6
-rw-r--r--gtk.py12
-rw-r--r--gtkmodule.c174
-rw-r--r--libglade.py61
-rw-r--r--libglademodule.c38
7 files changed, 234 insertions, 68 deletions
diff --git a/ChangeLog b/ChangeLog
index ec078076..73e9de7b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/gtk.py b/gtk.py
index 4731d874..7b01ce11 100644
--- a/gtk.py
+++ b/gtk.py
@@ -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,