def _enable_dnd(self): def on_drag_start(widget, context): torrent_ids = self._view.get_selected_torrents() widget._tv_dnd_data = torrent_ids def load_ids(widget, path, col, selection, *args): #torrent_ids = widget.get_data("dnd_data") torrent_ids = widget._tv_dnd_data data = pickle.dumps(torrent_ids) selection.set(Gdk.Atom.intern("TEXT", False), 8, data) return True def get_drag_icon(widget, x, y): if widget.get_selection().count_selected_rows() > 1: pixbuf = icon_multiple else: pixbuf = icon_single return (pixbuf, 0, 0) icon_single = Gtk.IconTheme.get_default().load_icon( 'gtk-dnd', Gtk.IconSize.DND, 0) icon_multiple = Gtk.IconTheme.get_default().load_icon( 'gtk-dnd-multiple', Gtk.IconSize.DND, 0) src_target = DragTarget( name="torrent_ids", scope=Gtk.TargetFlags.SAME_APP, action=Gdk.DragAction.MOVE, data_func=load_ids, ) self._dnd_src_proxy = TreeViewDragSourceProxy(self._view.treeview, get_drag_icon, on_drag_start) self._dnd_src_proxy.add_target(src_target) if __debug__: RT.register(src_target, __name__) if __debug__: RT.register(self._dnd_src_proxy, __name__)
def _enable_dnd(self): # Source Proxy def load_row(widget, path, col, selection, *args): model = widget.get_model() iter_ = model.get_iter(path) path_str = bytes(model.get_string_from_iter(iter_), encoding='utf8') selection.set(Gdk.Atom.intern("TEXT", False), 8, path_str) return True def get_drag_icon(widget, x, y): return (icon_single, 0, 0) # Destination Proxy def check_dest_id(widget, path, col, pos, selection, *args): model = widget.get_model() id = model[path][LABEL_ID] if id == ID_NONE or self._store.is_user_label(id): return True def receive_ids(widget, path, col, pos, selection, *args): try: torrent_ids = pickle.loads(selection.get_data()) except: return False model = widget.get_model() id = model[path][LABEL_ID] if id == ID_NONE or self._store.is_user_label(id): log.info("Setting label %r on %r", self._store[id]["fullname"], torrent_ids) client.labelplus.set_torrent_labels(torrent_ids, id) return True def check_dest_row(widget, path, col, pos, selection, *args): model = widget.get_model() id = model[path][LABEL_ID] try: src_path = str(selection.get_data(), encoding='utf8') src_id = model[src_path][LABEL_ID] except IndexError: return False if (id == src_id or labelplus.common.label.is_ancestor(src_id, id) or not self._store.is_user_label(src_id)): return False if id == ID_NONE: children = self._store.get_descendent_ids(ID_NULL, 1) elif self._store.is_user_label(id): children = self._store[id]["children"] else: return False src_name = self._store[src_id]["name"] for child in children: if child in self._store and self._store[child][ "name"] == src_name: return False return True def receive_row(widget, path, col, pos, selection, *args): if not check_dest_row(widget, path, col, pos, selection, *args): return False model = widget.get_model() dest_id = model[path][LABEL_ID] src_path = str(selection.get_data(), encoding='utf8') src_id = model[src_path][LABEL_ID] src_name = self._store[src_id]["name"] if dest_id != ID_NONE: dest_name = "%s/%s" % (self._store[dest_id]["fullname"], src_name) else: dest_id = ID_NULL dest_name = src_name log.info("Renaming label: %r -> %r", self._store[src_id]["fullname"], dest_name) client.labelplus.move_label(src_id, dest_id, src_name) # Default drag source will delete row on success, so return failure return False icon_single = Gtk.IconTheme.get_default().load_icon( 'gtk-dnd', Gtk.IconSize.DND, 0) src_target = DragTarget( name="label_row", scope=Gtk.TargetFlags.SAME_APP, action=Gdk.DragAction.MOVE, data_func=load_row, ) self._dnd_src_proxy = TreeViewDragSourceProxy(self._tree, get_drag_icon) self._dnd_src_proxy.add_target(src_target) if __debug__: RT.register(src_target, __name__) if __debug__: RT.register(self._dnd_src_proxy, __name__) ids_target = DragTarget( name="torrent_ids", scope=Gtk.TargetFlags.SAME_APP, action=Gdk.DragAction.MOVE, pos=Gtk.TreeViewDropPosition.INTO_OR_BEFORE, data_func=receive_ids, aux_func=check_dest_id, ) row_target = DragTarget( name="label_row", scope=Gtk.TargetFlags.SAME_APP, action=Gdk.DragAction.MOVE, pos=Gtk.TreeViewDropPosition.INTO_OR_BEFORE, data_func=receive_row, aux_func=check_dest_row, ) self._dnd_dest_proxy = TreeViewDragDestProxy(self._tree) self._dnd_dest_proxy.add_target(ids_target) self._dnd_dest_proxy.add_target(row_target) if __debug__: RT.register(ids_target, __name__) if __debug__: RT.register(row_target, __name__) if __debug__: RT.register(self._dnd_dest_proxy, __name__)