mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Edit book: File browser: Allow using keyboard shortcuts to re-order the spine
This commit is contained in:
parent
6e5a424640
commit
c24f59151c
@ -133,11 +133,14 @@ Changing text file order
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can re-arrange the order in which text (HTML) files are opened when reading
|
||||
the book by simply dragging and dropping them in the Files browser. For the
|
||||
technically inclined, this is called re-ordering the book spine. Note that you
|
||||
have to drop the items *between* other items, not on top of them, this can be a
|
||||
little fiddly until you get used to it. Dropping on top of another file will
|
||||
cause the files to be merged.
|
||||
the book by simply dragging and dropping them in the Files browser or clicking
|
||||
on the file to move and then pressing the :kbd:`Ctrl+Shift` modifiers with the
|
||||
:kbd:`Up`, :kbd:`Down`, :kbd:`Home` or :kbd:`End` keys. For the technically
|
||||
inclined, this is called re-ordering the book spine.
|
||||
|
||||
Note that you have to drop the items *between* other items, not on top of them,
|
||||
this can be a little fiddly until you get used to it. Dropping on top of
|
||||
another file will cause the files to be merged.
|
||||
|
||||
Marking the cover
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -374,6 +374,9 @@ class FileList(QTreeWidget, OpenWithHandler):
|
||||
return
|
||||
new_names = new_names[:insertion_point] + names + new_names[insertion_point:]
|
||||
order = [[name, linear_map[name]] for name in new_names]
|
||||
self.request_reorder(order)
|
||||
|
||||
def request_reorder(self, order):
|
||||
# Ensure that all non-linear items are at the end, by making any non-linear
|
||||
# items not at the end, linear
|
||||
for i, (name, linear) in tuple(enumerate(order)):
|
||||
@ -797,9 +800,20 @@ class FileList(QTreeWidget, OpenWithHandler):
|
||||
self.mark_requested.emit(name, 'nav')
|
||||
|
||||
def keyPressEvent(self, ev):
|
||||
if ev.key() in (Qt.Key.Key_Delete, Qt.Key.Key_Backspace):
|
||||
k = ev.key()
|
||||
mods = ev.modifiers() & (
|
||||
Qt.KeyboardModifier.ShiftModifier | Qt.KeyboardModifier.AltModifier | Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.MetaModifier)
|
||||
if k in (Qt.Key.Key_Delete, Qt.Key.Key_Backspace):
|
||||
ev.accept()
|
||||
self.request_delete()
|
||||
elif mods == (Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.ShiftModifier):
|
||||
m = self.categories['text'].childCount()
|
||||
amt = {Qt.Key.Key_Up: -1, Qt.Key.Key_Down: 1, Qt.Key.Key_Home: -m, Qt.Key.Key_End: m}.get(k, None)
|
||||
if amt is not None:
|
||||
ev.accept()
|
||||
self.move_selected_text_items(amt)
|
||||
else:
|
||||
return QTreeWidget.keyPressEvent(self, ev)
|
||||
else:
|
||||
return QTreeWidget.keyPressEvent(self, ev)
|
||||
|
||||
@ -861,6 +875,35 @@ class FileList(QTreeWidget, OpenWithHandler):
|
||||
ans.discard('')
|
||||
return ans
|
||||
|
||||
def move_selected_text_items(self, amt: int) -> bool:
|
||||
parent = self.categories['text']
|
||||
children = tuple(parent.child(i) for i in range(parent.childCount()))
|
||||
selected_names = tuple(c.data(0, NAME_ROLE) for c in children if c.isSelected())
|
||||
if not selected_names or amt == 0:
|
||||
return False
|
||||
current_order = tuple(c.data(0, NAME_ROLE) for c in children)
|
||||
linear_map = {c.data(0, NAME_ROLE):c.data(0, LINEAR_ROLE) for c in children}
|
||||
order_map = {name: i for i, name in enumerate(current_order)}
|
||||
new_order = list(current_order)
|
||||
changed = False
|
||||
items = reversed(selected_names) if amt > 0 else selected_names
|
||||
if amt < 0:
|
||||
items = selected_names
|
||||
delta = max(amt, -order_map[selected_names[0]])
|
||||
else:
|
||||
items = reversed(selected_names)
|
||||
delta = min(amt, len(children) - 1 - order_map[selected_names[-1]])
|
||||
for name in items:
|
||||
i = order_map[name]
|
||||
new_i = min(max(0, i + delta), len(current_order) - 1)
|
||||
if new_i != i:
|
||||
changed = True
|
||||
del new_order[i]
|
||||
new_order.insert(new_i, name)
|
||||
if changed:
|
||||
self.request_reorder([[n, linear_map[n]] for n in new_order])
|
||||
return changed
|
||||
|
||||
def copy_selected_files(self):
|
||||
self.initiate_file_copy.emit(self.selected_names)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user