Add Ctrl-X cut and paste-above-selection
Cut (Ctrl-X) marks the selection on the clipboard with a `cut` flag; a paste of a cut from a real playlist is a *move* (single-undo across playlists via move_tracks_between_playlists; same-playlist reorders), while a copy — or a cut from the library, which has nothing to remove — just adds. Paste now inserts *above the selected track* rather than appending. Cut/Paste added to the track context menu; parse_tracks_mime now tolerates a None/empty clipboard.
This commit is contained in:
@@ -234,6 +234,39 @@ class LibraryManager(QObject):
|
||||
self._set_track_ids(pid, after)
|
||||
self._push_track_ids("Reorder Playlist", pid, before, after)
|
||||
|
||||
def move_tracks_between_playlists(self, src_pid: str, src_rows: list[int],
|
||||
dest_pid: str, dest_position: int | None = None):
|
||||
"""Cut tracks out of one playlist and insert them into another as a
|
||||
single undoable move (Ctrl-X / Ctrl-V across playlists). For the same
|
||||
playlist, use move_tracks_in_playlist instead."""
|
||||
src = self.library.playlists.get(src_pid)
|
||||
dest = self.library.playlists.get(dest_pid)
|
||||
if (not src or not dest or src_pid == dest_pid
|
||||
or dest.playlist_type == PlaylistType.FOLDER):
|
||||
return
|
||||
src_before = list(src.track_ids)
|
||||
dest_before = list(dest.track_ids)
|
||||
rows = sorted(set(r for r in src_rows if 0 <= r < len(src_before)))
|
||||
if not rows:
|
||||
return
|
||||
moving = [src_before[r] for r in rows]
|
||||
src_after = [tid for i, tid in enumerate(src_before) if i not in rows]
|
||||
dest_after = list(dest_before)
|
||||
if dest_position is None or dest_position >= len(dest_after):
|
||||
dest_after.extend(moving)
|
||||
else:
|
||||
dest_after[dest_position:dest_position] = moving
|
||||
|
||||
def apply(src_ids, dest_ids):
|
||||
self._set_track_ids(src_pid, src_ids)
|
||||
self._set_track_ids(dest_pid, dest_ids)
|
||||
|
||||
apply(src_after, dest_after)
|
||||
self.undo_stack.push(Command(
|
||||
"Move to Playlist",
|
||||
undo=lambda: apply(src_before, dest_before),
|
||||
redo=lambda: apply(src_after, dest_after)))
|
||||
|
||||
def _set_track_ids(self, pid: str, ids: list[int]):
|
||||
playlist = self.library.playlists.get(pid)
|
||||
if playlist is None:
|
||||
|
||||
Reference in New Issue
Block a user