From 68f624addd356c8ef61e1085b51c5bec5e08b09e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 29 Jul 2020 13:43:19 +0530 Subject: [PATCH] Fix #1888251 [Selecting multiple entries in menu editor only moves one](https://bugs.launchpad.net/calibre/+bug/1888251) --- src/calibre/gui2/preferences/toolbar.py | 37 +++++++++++++++---------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/calibre/gui2/preferences/toolbar.py b/src/calibre/gui2/preferences/toolbar.py index 4104f3a506..cf0b6bb57b 100644 --- a/src/calibre/gui2/preferences/toolbar.py +++ b/src/calibre/gui2/preferences/toolbar.py @@ -6,8 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' -from PyQt5.Qt import QAbstractListModel, Qt, QIcon, \ - QItemSelectionModel +from PyQt5.Qt import QAbstractListModel, Qt, QIcon from calibre import force_unicode from calibre.gui2.preferences.toolbar_ui import Ui_Form @@ -167,9 +166,7 @@ class CurrentModel(BaseModel): def move(self, idx, delta): row = idx.row() - if row < 0 or row >= len(self._data): - return - nrow = row + delta + nrow = (row + delta + len(self._data)) % len(self._data) if nrow < 0 or nrow >= len(self._data): return t = self._data[row] @@ -180,6 +177,14 @@ class CurrentModel(BaseModel): self.dataChanged.emit(ni, ni) return ni + def move_many(self, indices, delta): + indices = sorted(indices, key=lambda i: i.row(), reverse=delta > 0) + ans = {} + for idx in indices: + ni = self.move(idx, delta) + ans[idx.row()] = ni + return ans + def add(self, names): actions = [] reject = set() @@ -330,15 +335,19 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.changed_signal.emit() def move(self, delta, *args): - ci = self.current_actions.currentIndex() - m = self.current_actions.model() - if ci.isValid(): - ni = m.move(ci, delta) - if ni is not None: - self.current_actions.setCurrentIndex(ni) - self.current_actions.selectionModel().select(ni, - QItemSelectionModel.ClearAndSelect) - self.changed_signal.emit() + sm = self.current_actions.selectionModel() + x = sm.selectedIndexes() + if x and len(x): + i = sm.currentIndex().row() + m = self.current_actions.model() + idx_map = m.move_many(x, delta) + newci = idx_map.get(i) + if newci is not None: + sm.setCurrentIndex(newci, sm.ClearAndSelect) + sm.clear() + for idx in idx_map.values(): + sm.select(idx, sm.Select) + self.changed_signal.emit() def commit(self): # Ensure preferences are showing in either the toolbar or