From 6a4bd7dceb72398704a4e37d1b204a400b22c21e Mon Sep 17 00:00:00 2001 From: Josip Date: Fri, 2 Jun 2017 23:22:06 +0200 Subject: [PATCH] Crash after dragging multiple items from clipboard to gallery I copied 7 items from the Media List to the clipboard. I then opened a Person, and dragged one Media Item to the Gallery. I then clicked and dragged to highlight the remaining 6 items at once. On dragging them to the gallery, it crashed. 2989475: ERROR: grampsapp.py: line 145: Unhandled exception Traceback (most recent call last): File "C:\Program Files\GrampsAIO64-4.2.5\gramps\gui\editors\displaytabs\gallerytab.py", line 475, in drag_data_received (mytype, selfid, obj, row_from) = pickle.loads(sel_data.get_data()) ValueError: too many values to unpack (expected 4) Fixes #9984. --- gramps/gui/editors/displaytabs/gallerytab.py | 75 ++++++++++++-------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/gramps/gui/editors/displaytabs/gallerytab.py b/gramps/gui/editors/displaytabs/gallerytab.py index 25bb31b74..a5c03d037 100644 --- a/gramps/gui/editors/displaytabs/gallerytab.py +++ b/gramps/gui/editors/displaytabs/gallerytab.py @@ -467,42 +467,55 @@ class GalleryTab(ButtonTab, DbGUIElement): and decide if this is a move or a reorder. """ if sel_data and sel_data.get_data(): + sel_list = [] try: - (mytype, selfid, obj, row_from) = pickle.loads(sel_data.get_data()) + rets = pickle.loads(sel_data.get_data()) - # make sure this is the correct DND type for this object - if mytype == self._DND_TYPE.drag_type: + # single dnd item + if isinstance(rets, tuple): + sel_list.append(rets) - # determine the destination row - data = self.iconlist.get_dest_item_at_pos(x, y) - if data: - (path, pos) = data - row = path.get_indices()[0] - if pos == Gtk.IconViewDropPosition.DROP_LEFT: - row = max(row, 0) - elif pos == Gtk.IconViewDropPosition.DROP_RIGHT: - row = min(row, len(self.get_data())) - elif pos == Gtk.IconViewDropPosition.DROP_INTO: - row = min(row+1, len(self.get_data())) - else: - row = len(self.get_data()) + # multiple dnd items + elif isinstance(rets, list): + for ret in rets: + sel_list.append(pickle.loads(ret)) - # if the is same object, we have a move, otherwise, - # it is a standard drag-n-drop + for sel in sel_list: + (mytype, selfid, obj, row_from) = sel - if id(self) == selfid: - self._move(row_from, row, obj) - else: - self._handle_drag(row, obj) - self.rebuild() - elif mytype == DdTargets.MEDIAOBJ.drag_type: - oref = MediaRef() - oref.set_reference_handle(obj) - self.get_data().append(oref) - self.changed = True - self.rebuild() - elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type: - self.handle_extra_type(mytype, obj) + # make sure this is the correct DND type for this object + if mytype == self._DND_TYPE.drag_type: + + # determine the destination row + data = self.iconlist.get_dest_item_at_pos(x, y) + if data: + (path, pos) = data + row = path.get_indices()[0] + if pos == Gtk.IconViewDropPosition.DROP_LEFT: + row = max(row, 0) + elif pos == Gtk.IconViewDropPosition.DROP_RIGHT: + row = min(row, len(self.get_data())) + elif pos == Gtk.IconViewDropPosition.DROP_INTO: + row = min(row+1, len(self.get_data())) + else: + row = len(self.get_data()) + + # if the is same object, we have a move, otherwise, + # it is a standard drag-n-drop + + if id(self) == selfid: + self._move(row_from, row, obj) + else: + self._handle_drag(row, obj) + self.rebuild() + elif mytype == DdTargets.MEDIAOBJ.drag_type: + oref = MediaRef() + oref.set_reference_handle(obj) + self.get_data().append(oref) + self.changed = True + self.rebuild() + elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type: + self.handle_extra_type(mytype, obj) except pickle.UnpicklingError: files = sel_data.get_uris() for file in files: