[pygtk] Fix GtkTreeView.set_drag_dest_row



commit 8122275fc42eafc12d90b5c829f1708f50da27fb
Author: Dieter Verfaillie <dieterv optionexplicit be>
Date:   Fri Dec 24 10:09:43 2010 +1300

    Fix GtkTreeView.set_drag_dest_row
    
    	* Accept None as first argument
    	* Add examples/gtk/treeview_dnd.py
    	* Fixes bug 637214

 examples/gtk/treeview_dnd.py |  124 ++++++++++++++++++++++++++++++++++++++++++
 gtk/gtktreeview.override     |   14 +++--
 2 files changed, 133 insertions(+), 5 deletions(-)
---
diff --git a/examples/gtk/treeview_dnd.py b/examples/gtk/treeview_dnd.py
new file mode 100644
index 0000000..0df1650
--- /dev/null
+++ b/examples/gtk/treeview_dnd.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+
+
+# This file is based on http://code.google.com/p/quodlibet/source/browse/junk/dndtest.py
+# For this test case, we're interested in the _drag_motion method of the TestTreeView class.
+
+
+import gobject
+import gtk
+
+
+class TestTreeView(gtk.TreeView):
+    __gtype_name__ = 'TestTreeView'
+    
+    def __init__(self, name):
+        gtk.TreeView.__init__(self)
+
+        model = gtk.ListStore(str)
+        for i in range(10): model.append(row=['Item%d' % i])
+        self.set_model(model)
+
+        crt = gtk.CellRendererText()
+        col = gtk.TreeViewColumn(name, crt, text=0)
+        self.append_column(col)
+
+        self.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
+        targets = [('text/uri-list', 0, 1)]
+        self.drag_source_set(gtk.gdk.BUTTON1_MASK|gtk.gdk.CONTROL_MASK,
+                             targets,
+                             gtk.gdk.ACTION_COPY|gtk.gdk.ACTION_MOVE)
+        self.drag_dest_set(gtk.DEST_DEFAULT_ALL,
+                           targets,
+                           gtk.gdk.ACTION_COPY|gtk.gdk.ACTION_MOVE)
+        self.connect('drag-begin', self._drag_begin)
+        self.connect('drag-data-delete', self._drag_data_delete)
+        self.connect('drag-motion', self._drag_motion)
+        self.connect('drag-data-get', self._drag_data_get)
+        self.connect('drag-data-received', self._drag_data_received)
+
+    def _drag_begin(self, view, ctx):
+        return True
+
+    def _drag_data_delete(self, view, ctx):
+        if ctx.is_source and ctx.action == gtk.gdk.ACTION_MOVE:
+            # For some reason this gets called twice.
+            map(self.get_model().remove, self.__iters)
+            self.__iters = []
+
+    def _drag_motion(self, view, ctx, x, y, time):
+        #try:
+        #    self.set_drag_dest_row(*self.get_dest_row_at_pos(x, y))
+        #except TypeError:
+        #    self.set_drag_dest_row(len(self.get_model()) - 1, gtk.TREE_VIEW_DROP_AFTER)
+        try:
+            print 'Testing set_drag_dest_row(None, pos)'
+            (path, pos) = self.get_dest_row_at_pos(x, y)
+            self.set_drag_dest_row(None, pos)
+        except TypeError:
+            self.set_drag_dest_row(len(self.get_model()) - 1, gtk.TREE_VIEW_DROP_AFTER)
+
+
+        if ctx.get_source_widget() == self:
+            kind = gtk.gdk.ACTION_MOVE
+        else:
+            kind = gtk.gdk.ACTION_COPY
+
+        ctx.drag_status(kind, time)
+        return True
+
+    def _drag_data_get(self, view, ctx, sel, tid, etime):
+        model, paths = self.get_selection().get_selected_rows()
+        uris = ['file:///' + model[path][0] for path in paths]
+
+        if tid == 1:
+            if ctx.action == gtk.gdk.ACTION_MOVE:
+                self.__iters = map(model.get_iter, paths)
+            else:
+                self.__iters = []
+
+            sel.set('text/uri-list', 8, '\x00'.join(uris))
+        else:
+            sel.set_uris(uris)
+
+            return True
+
+    def _drag_data_received(self, view, ctx, x, y, sel, info, etime):
+        model = view.get_model()
+
+        if info == 1:
+            files = sel.data.split('\x00')
+        elif info == 2:
+            files = sel.get_uris()
+
+        try:
+            path, position = self.get_dest_row_at_pos(x, y)
+        except TypeError:
+            path, position = len(model) - 1, gtk.TREE_VIEW_DROP_AFTER
+
+        iter = model.get_iter(path)
+        file = files.pop(0)
+
+        if position in (gtk.TREE_VIEW_DROP_BEFORE, gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
+            iter = model.insert_before(iter, [file[8:]])
+        else:
+            iter = model.insert_after(iter, [file[8:]])
+
+        for file in files:
+            iter = model.insert_after(iter, [file[8:]])
+
+        ctx.finish(True, True, etime)
+        return True
+
+
+if __name__ == '__main__':
+    w = gtk.Window()
+    w.connect('delete-event', gtk.main_quit)
+    w.add(gtk.HBox(spacing=3))
+    w.child.pack_start(TestTreeView('Test 1'))
+    w.child.pack_start(TestTreeView('Test 2'))
+    w.show_all()
+    gtk.main()
+
+
+
diff --git a/gtk/gtktreeview.override b/gtk/gtktreeview.override
index 82e6f3c..62fec01 100644
--- a/gtk/gtktreeview.override
+++ b/gtk/gtktreeview.override
@@ -2774,11 +2774,15 @@ _wrap_gtk_tree_view_set_drag_dest_row(PyGObject *self, PyObject *args,
                                      &py_path, &py_pos))
         return NULL;
     
-    path = pygtk_tree_path_from_pyobject(py_path);
-    if (!path) {
-        PyErr_SetString(PyExc_TypeError,
-                        "set_drag_dest_row muts be a TreePath");
-        return NULL;
+    if (py_path == Py_None)
+        path = NULL;
+    else {
+        path = pygtk_tree_path_from_pyobject(py_path);
+        if (!path) {
+            PyErr_SetString(PyExc_TypeError,
+                            "set_drag_dest_row must be a TreePath");
+            return NULL;
+        }
     }
     pos = (GtkTreeViewDropPosition) py_pos;
     gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(self->obj), path, pos);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]