mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Cover grid: Fix dragging the mouse while holding shift to extend the selection not working well. Fixes #2054617 [Multiple book selection in cover grid using mouse and shift key](https://bugs.launchpad.net/calibre/+bug/2054617)
This commit is contained in:
parent
e1238ea3ee
commit
275cfd4875
@ -210,15 +210,18 @@ def drag_data(self):
|
|||||||
|
|
||||||
|
|
||||||
def mouseMoveEvent(self, event):
|
def mouseMoveEvent(self, event):
|
||||||
if not self.drag_allowed:
|
|
||||||
return
|
|
||||||
if self.drag_start_pos is None:
|
|
||||||
return qt_item_view_base_class(self).mouseMoveEvent(self, event)
|
|
||||||
|
|
||||||
if self.event_has_mods():
|
if self.event_has_mods():
|
||||||
self.drag_start_pos = None
|
self.drag_start_pos = None
|
||||||
|
if not self.drag_allowed:
|
||||||
|
if hasattr(self, 'handle_mouse_move_event'):
|
||||||
|
self.handle_mouse_move_event(event)
|
||||||
|
return
|
||||||
|
if self.drag_start_pos is None:
|
||||||
|
if hasattr(self, 'handle_mouse_move_event'):
|
||||||
|
self.handle_mouse_move_event(event)
|
||||||
|
else:
|
||||||
|
qt_item_view_base_class(self).mouseMoveEvent(self, event)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not (event.buttons() & Qt.MouseButton.LeftButton) or \
|
if not (event.buttons() & Qt.MouseButton.LeftButton) or \
|
||||||
(event.pos() - self.drag_start_pos).manhattanLength() \
|
(event.pos() - self.drag_start_pos).manhattanLength() \
|
||||||
< QApplication.startDragDistance():
|
< QApplication.startDragDistance():
|
||||||
@ -727,6 +730,7 @@ class GridView(QListView):
|
|||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
QListView.__init__(self, parent)
|
QListView.__init__(self, parent)
|
||||||
|
self.shift_click_start_data = None
|
||||||
self.dbref = lambda: None
|
self.dbref = lambda: None
|
||||||
self._ncols = None
|
self._ncols = None
|
||||||
self.gesture_manager = GestureManager(self)
|
self.gesture_manager = GestureManager(self)
|
||||||
@ -1160,21 +1164,54 @@ class GridView(QListView):
|
|||||||
def restore_hpos(self, hpos):
|
def restore_hpos(self, hpos):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def handle_mouse_move_event(self, ev):
|
||||||
|
# handle shift drag to extend selections
|
||||||
|
if not QApplication.keyboardModifiers() & Qt.KeyboardModifier.ShiftModifier:
|
||||||
|
return super().mouseMoveEvent(ev)
|
||||||
|
index = self.indexAt(ev.pos())
|
||||||
|
if not index.isValid() or not self.shift_click_start_data:
|
||||||
|
return
|
||||||
|
m = self.model()
|
||||||
|
ci = m.index(self.shift_click_start_data[0], 0)
|
||||||
|
if not ci.isValid():
|
||||||
|
return
|
||||||
|
sm = self.selectionModel()
|
||||||
|
sm.setCurrentIndex(index, QItemSelectionModel.SelectionFlag.NoUpdate)
|
||||||
|
if not sm.hasSelection():
|
||||||
|
sm.select(index, QItemSelectionModel.SelectionFlag.ClearAndSelect)
|
||||||
|
return True
|
||||||
|
cr = ci.row()
|
||||||
|
tgt = index.row()
|
||||||
|
if cr == tgt:
|
||||||
|
sm.select(index, QItemSelectionModel.SelectionFlag.Select)
|
||||||
|
return
|
||||||
|
if cr < tgt:
|
||||||
|
# mouse is moved after the start pos
|
||||||
|
top = min(self.shift_click_start_data[1], cr)
|
||||||
|
bottom = tgt
|
||||||
|
else:
|
||||||
|
top = tgt
|
||||||
|
bottom = max(self.shift_click_start_data[2], cr)
|
||||||
|
sm.select(QItemSelection(m.index(top, 0), m.index(bottom, 0)), QItemSelectionModel.SelectionFlag.ClearAndSelect)
|
||||||
|
|
||||||
def handle_mouse_press_event(self, ev):
|
def handle_mouse_press_event(self, ev):
|
||||||
if QApplication.keyboardModifiers() & Qt.KeyboardModifier.ShiftModifier:
|
# Shift-Click in QListView is broken. It selects extra items in
|
||||||
# Shift-Click in QListView is broken. It selects extra items in
|
# various circumstances, for example, click on some item in the
|
||||||
# various circumstances, for example, click on some item in the
|
# middle of a row then click on an item in the next row, all items
|
||||||
# middle of a row then click on an item in the next row, all items
|
# in the first row will be selected instead of only items after the
|
||||||
# in the first row will be selected instead of only items after the
|
# middle item.
|
||||||
# middle item.
|
if not QApplication.keyboardModifiers() & Qt.KeyboardModifier.ShiftModifier:
|
||||||
index = self.indexAt(ev.pos())
|
return super().mousePressEvent(ev)
|
||||||
if not index.isValid():
|
self.shift_click_start_data = None
|
||||||
return
|
index = self.indexAt(ev.pos())
|
||||||
ci = self.currentIndex()
|
if not index.isValid():
|
||||||
sm = self.selectionModel()
|
return
|
||||||
sm.setCurrentIndex(index, QItemSelectionModel.SelectionFlag.NoUpdate)
|
sm = self.selectionModel()
|
||||||
|
ci = self.currentIndex()
|
||||||
|
try:
|
||||||
if not ci.isValid():
|
if not ci.isValid():
|
||||||
return
|
return
|
||||||
|
sm.setCurrentIndex(index, QItemSelectionModel.SelectionFlag.NoUpdate)
|
||||||
if not sm.hasSelection():
|
if not sm.hasSelection():
|
||||||
sm.select(index, QItemSelectionModel.SelectionFlag.ClearAndSelect)
|
sm.select(index, QItemSelectionModel.SelectionFlag.ClearAndSelect)
|
||||||
return
|
return
|
||||||
@ -1183,8 +1220,16 @@ class GridView(QListView):
|
|||||||
top = self.model().index(min(cr, tgt), 0)
|
top = self.model().index(min(cr, tgt), 0)
|
||||||
bottom = self.model().index(max(cr, tgt), 0)
|
bottom = self.model().index(max(cr, tgt), 0)
|
||||||
sm.select(QItemSelection(top, bottom), QItemSelectionModel.SelectionFlag.Select)
|
sm.select(QItemSelection(top, bottom), QItemSelectionModel.SelectionFlag.Select)
|
||||||
else:
|
finally:
|
||||||
return QListView.mousePressEvent(self, ev)
|
min_row = self.model().rowCount(QModelIndex())
|
||||||
|
max_row = -1
|
||||||
|
for idx in sm.selectedIndexes():
|
||||||
|
r = idx.row()
|
||||||
|
if r < min_row:
|
||||||
|
min_row = r
|
||||||
|
elif r > max_row:
|
||||||
|
max_row = r
|
||||||
|
self.shift_click_start_data = index.row(), min_row, max_row
|
||||||
|
|
||||||
def indices_for_merge(self, resolved=True):
|
def indices_for_merge(self, resolved=True):
|
||||||
return self.selectionModel().selectedIndexes()
|
return self.selectionModel().selectedIndexes()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user