Compare commits
No commits in common. "f19fc2e8c0a0739effbf03b6f8e01cc5995e6d73" and "ff81447902276fd1a62b9ae201aa9ab07b59ed66" have entirely different histories.
f19fc2e8c0
...
ff81447902
@ -534,7 +534,6 @@ class RowAndTrack:
|
|||||||
return (
|
return (
|
||||||
f"<RowAndTrack(playlist_id={self.playlist_id}, "
|
f"<RowAndTrack(playlist_id={self.playlist_id}, "
|
||||||
f"row_number={self.row_number}, "
|
f"row_number={self.row_number}, "
|
||||||
f"playlistrow_id={self.playlistrow_id}, "
|
|
||||||
f"note={self.note}, track_id={self.track_id}>"
|
f"note={self.note}, track_id={self.track_id}>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import sys
|
|||||||
# PyQt imports
|
# PyQt imports
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
|
import line_profiler
|
||||||
from sqlalchemy import (
|
from sqlalchemy import (
|
||||||
bindparam,
|
bindparam,
|
||||||
delete,
|
delete,
|
||||||
@ -563,6 +564,7 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@line_profiler.profile
|
||||||
def update_plr_row_numbers(
|
def update_plr_row_numbers(
|
||||||
session: Session, playlist_id: int, sqla_map: List[dict[str, int]]
|
session: Session, playlist_id: int, sqla_map: List[dict[str, int]]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
@ -44,6 +44,7 @@ from PyQt6.QtWidgets import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
|
import line_profiler
|
||||||
import pipeclient
|
import pipeclient
|
||||||
from pygame import mixer
|
from pygame import mixer
|
||||||
from sqlalchemy.exc import IntegrityError
|
from sqlalchemy.exc import IntegrityError
|
||||||
@ -1068,12 +1069,13 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
else:
|
else:
|
||||||
webbrowser.get("browser").open_new_tab(url)
|
webbrowser.get("browser").open_new_tab(url)
|
||||||
|
|
||||||
def paste_rows(self) -> None:
|
@line_profiler.profile
|
||||||
|
def paste_rows(self, dummy_for_profiling=None) -> None:
|
||||||
"""
|
"""
|
||||||
Paste earlier cut rows.
|
Paste earlier cut rows.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not self.move_source_rows or not self.move_source_model:
|
if self.move_source_rows is None or self.move_source_model is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
to_playlist_model: PlaylistModel = self.active_tab().source_model
|
to_playlist_model: PlaylistModel = self.active_tab().source_model
|
||||||
@ -1083,16 +1085,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
else:
|
else:
|
||||||
destination_row = self.active_proxy_model().rowCount()
|
destination_row = self.active_proxy_model().rowCount()
|
||||||
|
|
||||||
# If we move a row to immediately under the current track, make
|
|
||||||
# that moved row the next track
|
|
||||||
set_next_row: Optional[int] = None
|
|
||||||
if (
|
|
||||||
track_sequence.current
|
|
||||||
and track_sequence.current.playlist_id == to_playlist_model.playlist_id
|
|
||||||
and destination_row == track_sequence.current.row_number + 1
|
|
||||||
):
|
|
||||||
set_next_row = destination_row
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
to_playlist_model.playlist_id
|
to_playlist_model.playlist_id
|
||||||
== self.move_source_model.source_model.playlist_id
|
== self.move_source_model.source_model.playlist_id
|
||||||
@ -1105,9 +1097,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.active_tab().resize_rows()
|
self.active_tab().resize_rows()
|
||||||
self.active_tab().clear_selection()
|
self.active_tab().clear_selection()
|
||||||
|
|
||||||
if set_next_row:
|
|
||||||
to_playlist_model.set_next_row(set_next_row)
|
|
||||||
|
|
||||||
def play_next(self, position: Optional[float] = None) -> None:
|
def play_next(self, position: Optional[float] = None) -> None:
|
||||||
"""
|
"""
|
||||||
Play next track, optionally from passed position.
|
Play next track, optionally from passed position.
|
||||||
|
|||||||
@ -26,6 +26,7 @@ from PyQt6.QtGui import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
|
import line_profiler
|
||||||
import obswebsocket # type: ignore
|
import obswebsocket # type: ignore
|
||||||
|
|
||||||
# import snoop # type: ignore
|
# import snoop # type: ignore
|
||||||
@ -736,7 +737,8 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
self.update_track_times()
|
self.update_track_times()
|
||||||
self.invalidate_rows(row_numbers)
|
self.invalidate_rows(row_numbers)
|
||||||
|
|
||||||
def move_rows(self, from_rows: list[int], to_row_number: int) -> None:
|
@line_profiler.profile
|
||||||
|
def move_rows(self, from_rows: list[int], to_row_number: int, dummy_for_profiling=None) -> None:
|
||||||
"""
|
"""
|
||||||
Move the playlist rows given to to_row and below.
|
Move the playlist rows given to to_row and below.
|
||||||
"""
|
"""
|
||||||
@ -783,6 +785,18 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
if old_row != new_row:
|
if old_row != new_row:
|
||||||
row_map[old_row] = new_row
|
row_map[old_row] = new_row
|
||||||
|
|
||||||
|
# Check to see whether any rows in track_sequence have moved
|
||||||
|
if track_sequence.previous and track_sequence.previous.row_number in row_map:
|
||||||
|
track_sequence.previous.row_number = row_map[
|
||||||
|
track_sequence.previous.row_number
|
||||||
|
]
|
||||||
|
if track_sequence.current and track_sequence.current.row_number in row_map:
|
||||||
|
track_sequence.current.row_number = row_map[
|
||||||
|
track_sequence.current.row_number
|
||||||
|
]
|
||||||
|
if track_sequence.next and track_sequence.next.row_number in row_map:
|
||||||
|
track_sequence.next.row_number = row_map[track_sequence.next.row_number]
|
||||||
|
|
||||||
# For SQLAlchemy, build a list of dictionaries that map playlistrow_id to
|
# For SQLAlchemy, build a list of dictionaries that map playlistrow_id to
|
||||||
# new row number:
|
# new row number:
|
||||||
sqla_map: list[dict[str, int]] = []
|
sqla_map: list[dict[str, int]] = []
|
||||||
@ -817,27 +831,26 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
# endRemoveRows and the row range must be contiguous. Process
|
# endRemoveRows and the row range must be contiguous. Process
|
||||||
# the highest rows first so the lower row numbers are unchanged
|
# the highest rows first so the lower row numbers are unchanged
|
||||||
row_groups = self._reversed_contiguous_row_groups(from_rows)
|
row_groups = self._reversed_contiguous_row_groups(from_rows)
|
||||||
|
next_to_row = to_row_number
|
||||||
|
|
||||||
# Prepare destination playlist for a reset
|
# Prepare destination playlist for a reset
|
||||||
self.signals.begin_reset_model_signal.emit(to_playlist_id)
|
self.signals.begin_reset_model_signal.emit(to_playlist_id)
|
||||||
|
|
||||||
with db.Session() as session:
|
with db.Session() as session:
|
||||||
|
# Make room in destination playlist
|
||||||
|
max_destination_row_number = PlaylistRows.get_last_used_row(
|
||||||
|
session, to_playlist_id
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
max_destination_row_number
|
||||||
|
and to_row_number <= max_destination_row_number
|
||||||
|
):
|
||||||
|
# Move the destination playlist rows down to make room.
|
||||||
|
PlaylistRows.move_rows_down(
|
||||||
|
session, to_playlist_id, to_row_number, len(from_rows)
|
||||||
|
)
|
||||||
|
|
||||||
for row_group in row_groups:
|
for row_group in row_groups:
|
||||||
# Make room in destination playlist
|
|
||||||
max_destination_row_number = PlaylistRows.get_last_used_row(
|
|
||||||
session, to_playlist_id
|
|
||||||
)
|
|
||||||
if (
|
|
||||||
max_destination_row_number
|
|
||||||
and to_row_number <= max_destination_row_number
|
|
||||||
):
|
|
||||||
# Move the destination playlist rows down to make room.
|
|
||||||
PlaylistRows.move_rows_down(
|
|
||||||
session, to_playlist_id, to_row_number, len(row_group)
|
|
||||||
)
|
|
||||||
next_to_row = to_row_number
|
|
||||||
|
|
||||||
super().beginRemoveRows(QModelIndex(), min(row_group), max(row_group))
|
super().beginRemoveRows(QModelIndex(), min(row_group), max(row_group))
|
||||||
for playlist_row in PlaylistRows.plrids_to_plrs(
|
for playlist_row in PlaylistRows.plrids_to_plrs(
|
||||||
session,
|
session,
|
||||||
@ -975,29 +988,14 @@ class PlaylistModel(QAbstractTableModel):
|
|||||||
# Update display
|
# Update display
|
||||||
self.invalidate_row(track_sequence.previous.row_number)
|
self.invalidate_row(track_sequence.previous.row_number)
|
||||||
|
|
||||||
def refresh_data(self, session: db.session) -> None:
|
@line_profiler.profile
|
||||||
"""Populate self.playlist_rows with playlist data"""
|
def refresh_data(self, session: db.session, dummy_for_profiling=None) -> None:
|
||||||
|
"""Populate dicts for data calls"""
|
||||||
|
|
||||||
# We used to clear self.playlist_rows each time but that's
|
# Populate self.playlist_rows with playlist data
|
||||||
# expensive and slow on big playlists
|
self.playlist_rows.clear()
|
||||||
|
|
||||||
# Note where each playlist_id is
|
|
||||||
plid_to_row: dict[int, int] = {}
|
|
||||||
for oldrow in self.playlist_rows:
|
|
||||||
plrdata = self.playlist_rows[oldrow]
|
|
||||||
plid_to_row[plrdata.playlistrow_id] = plrdata.row_number
|
|
||||||
|
|
||||||
# build a new playlist_rows
|
|
||||||
new_playlist_rows: dict[int, RowAndTrack] = {}
|
|
||||||
for p in PlaylistRows.get_playlist_rows(session, self.playlist_id):
|
for p in PlaylistRows.get_playlist_rows(session, self.playlist_id):
|
||||||
if p.id not in plid_to_row:
|
self.playlist_rows[p.row_number] = RowAndTrack(p)
|
||||||
new_playlist_rows[p.row_number] = RowAndTrack(p)
|
|
||||||
else:
|
|
||||||
new_playlist_rows[p.row_number] = self.playlist_rows[plid_to_row[p.id]]
|
|
||||||
new_playlist_rows[p.row_number].row_number = p.row_number
|
|
||||||
|
|
||||||
# Copy to self.playlist_rows
|
|
||||||
self.playlist_rows = new_playlist_rows
|
|
||||||
|
|
||||||
def refresh_row(self, session, row_number):
|
def refresh_row(self, session, row_number):
|
||||||
"""Populate dict for one row from database"""
|
"""Populate dict for one row from database"""
|
||||||
|
|||||||
@ -296,15 +296,6 @@ class PlaylistTab(QTableView):
|
|||||||
and 0 <= max(from_rows) <= self.source_model.rowCount()
|
and 0 <= max(from_rows) <= self.source_model.rowCount()
|
||||||
and 0 <= to_model_row <= self.source_model.rowCount()
|
and 0 <= to_model_row <= self.source_model.rowCount()
|
||||||
):
|
):
|
||||||
# If we move a row to immediately under the current track, make
|
|
||||||
# that moved row the next track
|
|
||||||
set_next_row: Optional[int] = None
|
|
||||||
if (
|
|
||||||
track_sequence.current
|
|
||||||
and to_model_row == track_sequence.current.row_number + 1
|
|
||||||
):
|
|
||||||
set_next_row = to_model_row
|
|
||||||
|
|
||||||
self.source_model.move_rows(from_rows, to_model_row)
|
self.source_model.move_rows(from_rows, to_model_row)
|
||||||
|
|
||||||
# Reset drag mode to allow row selection by dragging
|
# Reset drag mode to allow row selection by dragging
|
||||||
@ -316,10 +307,6 @@ class PlaylistTab(QTableView):
|
|||||||
# Resize rows
|
# Resize rows
|
||||||
self.resize_rows()
|
self.resize_rows()
|
||||||
|
|
||||||
# Set next row if we are immediately under current row
|
|
||||||
if set_next_row:
|
|
||||||
self.source_model.set_next_row(set_next_row)
|
|
||||||
|
|
||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
def mouseReleaseEvent(self, event):
|
def mouseReleaseEvent(self, event):
|
||||||
|
|||||||
@ -387,9 +387,9 @@ class TestMMMiscRowMove(unittest.TestCase):
|
|||||||
assert [int(a) for a in row_notes] == [
|
assert [int(a) for a in row_notes] == [
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
1,
|
|
||||||
3,
|
3,
|
||||||
4,
|
4,
|
||||||
|
1,
|
||||||
2,
|
2,
|
||||||
3,
|
3,
|
||||||
4,
|
4,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user