GNOME Bugzilla – Bug 116133
Add methods TreeView.enable_model_drag_*
Last modified: 2004-12-22 21:47:04 UTC
The methods: TreeView.enable_model_drag_source() TreeView.enable_model_drag_dest() weren't implemented yet. This is a patch that adds them to the file "gtktreeview.override". Patch is against latest CVS snapshot, tested on Linux.
--- gtk/gtktreeview.override~ Fri Jun 27 17:14:11 2003 +++ gtk/gtktreeview.override Fri Jun 27 17:10:15 2003 @@ -1809,4 +1809,96 @@ return Py_BuildValue("(ii)", width, height); } +%% +override gtk_tree_view_enable_model_drag_source kwargs +static PyObject * +_wrap_gtk_tree_view_enable_model_drag_source(PyGObject *self, PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "start_button_mask", "targets", "actions", NULL }; + PyObject *py_sbmask, *py_targets, *py_actions; + GdkModifierType sbmask; + GtkTargetEntry *targets; + GdkDragAction actions; + gint n_targets, i; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "OOO:GtkTreeView.enable_model_drag_source", + kwlist, + &py_sbmask, &py_targets, &py_actions)) + return NULL; + if (pyg_flags_get_value(GDK_TYPE_MODIFIER_TYPE, + py_sbmask, (gint *)&sbmask)) + return NULL; + if (pyg_flags_get_value(GDK_TYPE_DRAG_ACTION, + py_actions, (gint *)&actions)) + return NULL; + if (!PySequence_Check(py_targets)) { + PyErr_SetString(PyExc_TypeError, "targets must be a sequence"); + return NULL; + } + n_targets = PySequence_Length(py_targets); + targets = g_new(GtkTargetEntry, n_targets); + for (i = 0; i < n_targets; i++) { + PyObject *item = PySequence_GetItem(py_targets, i); + Py_DECREF(item); + if (!PyArg_ParseTuple(item, "zii", &targets[i].target, + &targets[i].flags, &targets[i].info)) { + PyErr_Clear(); + PyErr_SetString(PyExc_TypeError, + "list items should be of form (string,int,int)"); + g_free(targets); + return NULL; + } + } + gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(self->obj), + sbmask, targets, n_targets, actions); + g_free(targets); + Py_INCREF(Py_None); + return Py_None; +} +%% +override gtk_tree_view_enable_model_drag_dest kwargs +static PyObject * +_wrap_gtk_tree_view_enable_model_drag_dest(PyGObject *self, PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "targets", "actions", NULL }; + PyObject *py_targets, *py_actions; + GtkTargetEntry *targets; + GdkDragAction actions; + gint n_targets, i; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "OO:GtkTreeView.enable_model_drag_dest", + kwlist, + &py_targets, &py_actions)) + return NULL; + if (pyg_flags_get_value(GDK_TYPE_DRAG_ACTION, + py_actions, (gint *)&actions)) + return NULL; + if (!PySequence_Check(py_targets)) { + PyErr_SetString(PyExc_TypeError, "targets must be a sequence"); + return NULL; + } + n_targets = PySequence_Length(py_targets); + targets = g_new(GtkTargetEntry, n_targets); + for (i = 0; i < n_targets; i++) { + PyObject *item = PySequence_GetItem(py_targets, i); + Py_DECREF(item); + if (!PyArg_ParseTuple(item, "zii", &targets[i].target, + &targets[i].flags, &targets[i].info)) { + PyErr_Clear(); + PyErr_SetString(PyExc_TypeError, + "list items should be of form (string,int,int)"); + g_free(targets); + return NULL; + } + } + gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(self->obj), + targets, n_targets, actions); + g_free(targets); + Py_INCREF(Py_None); + return Py_None; +} +%%
Created attachment 17838 [details] [review] Add TreeView.enable_model_drag_* to gtktreeview.override
Created attachment 17840 [details] [review] More DnD methods for TreeView
[ Sorry for the mess, first time with bugzilla... ] Addendum: since the enable_model_drag_* methods are used with set_/get_drag_dest_row, in order to handle the dragged row, I've added them too. Complete patch attached.
*** Bug 113552 has been marked as a duplicate of this bug. ***
hey, bassi emmanuele :) Thanks for the patch :) works fine ^^ however, how can one handle the actual drop ? connect to the usual drag-data-received signal? And then? I thought about using something to the extents of this in the callback: path, pos = widget.get_dest_row_at_pos(x,y,path,pos) widget.set_drag_dest_row(path, pos) (get_dest_row_at_pos isn't wrapped tho) however, this is just a guess since I didnt do treeview dnd yet :) do you happen to have an example lying around ? ^^
I've implemented the set/get_drag_dest_row in the second patch attached to this report. I've tried to experiment some DnD with treeview, but insofar all that I've come up with was a very lousy test case; I've never used DnD in C either, so I'd need a working example too. :-) I've posted a working reorderable treeview here: http://www.daa.com.au/pipermail/pygtk/2003-June/005367.html (it still uses the unpatched pygtk), along with a report of strange behaviour.
Thank you for the patch. I have committed it in CVS.
hi again, I cant seem to quite drop something in a tree at a specific position without having the function get_dest_row_at_pos... dragging something out of the tree is fine though :)
Created attachment 18581 [details] [review] gtk_tree_view_get_dest_row_at_po wrapper: even more treeview dnd stuff :)
kinda like so ;) intended to be used like this: def drag_data_received_cb(self, widget, context, x, y, seldata, info, time): q = widget.get_dest_row_at_pos(x,y) # <--- new if q != None: path, pos = q widget.set_drag_dest_row(path, pos) .... tree.connect("drag-data-received", self.drag_data_received_cb) and the usual enable_model_drag_* calls ...
reopenning bug so it doesn't get lost. I'll make sure I commit this before the next release. Please open new bugs for things like this in the future.
committed.