From 8122275fc42eafc12d90b5c829f1708f50da27fb Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Fri, 24 Dec 2010 10:09:43 +1300 Subject: 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 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 examples/gtk/treeview_dnd.py (limited to 'examples') diff --git a/examples/gtk/treeview_dnd.py b/examples/gtk/treeview_dnd.py new file mode 100644 index 00000000..0df1650c --- /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() + + + -- cgit v1.2.1