WIP V3: select next track works with caveats

Peformance isn't great
Selecting a non-existent track isn't caught
This commit is contained in:
Keith Edmunds 2023-11-01 22:53:25 +00:00
parent d9ad001c75
commit e137045812
4 changed files with 93 additions and 56 deletions

View File

@ -80,7 +80,7 @@ class MusicMusterSignals(QObject):
add_track_to_header_signal = pyqtSignal(int, int, int)
add_track_to_playlist_signal = pyqtSignal(int, int, int, str)
enable_escape_signal = pyqtSignal(bool)
set_next_track_signal = pyqtSignal(int, int)
next_track_changed_signal = pyqtSignal()
span_cells_signal = pyqtSignal(int, int, int, int)
def __post_init__(self):
@ -111,6 +111,7 @@ class PlaylistTrack:
self.path: Optional[str] = None
self.playlist_id: Optional[int] = None
self.plr_id: Optional[int] = None
self.plr_rownum: Optional[int] = None
self.silence_at: Optional[int] = None
self.start_gap: Optional[int] = None
self.start_time: Optional[datetime] = None
@ -120,7 +121,7 @@ class PlaylistTrack:
def __repr__(self) -> str:
return (
f"<PlaylistTrack(title={self.title}, artist={self.artist}, "
f"playlist_id={self.playlist_id}>"
f"plr_rownum={self.plr_rownum}, playlist_id={self.playlist_id}>"
)
def set_plr(self, session: scoped_session, plr: PlaylistRows) -> None:
@ -142,6 +143,7 @@ class PlaylistTrack:
self.path = track.path
self.playlist_id = plr.playlist_id
self.plr_id = plr.id
self.plr_rownum = plr.plr_rownum
self.silence_at = track.silence_at
self.start_gap = track.start_gap
self.start_time = None

View File

@ -553,6 +553,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.txtSearch.returnPressed.connect(self.search_playlist_return)
self.signals.enable_escape_signal.connect(self.enable_escape)
self.signals.next_track_changed_signal.connect(self.update_headers)
self.timer10.timeout.connect(self.tick_10ms)
self.timer500.timeout.connect(self.tick_500ms)
@ -1422,6 +1423,15 @@ class Window(QMainWindow, Ui_MainWindow):
self.splitter.setSizes([splitter_top, splitter_bottom])
return
def set_selected_track_next(self) -> None:
"""
Set currently-selected row on visible playlist tab as next track
"""
playlist_tab = self.active_tab()
if playlist_tab:
playlist_tab.set_row_as_next_track()
def set_tab_colour(self, widget: PlaylistTab, colour: QColor) -> None:
"""
Find the tab containing the widget and set the text colour
@ -1514,19 +1524,6 @@ class Window(QMainWindow, Ui_MainWindow):
# May also be called when last tab is closed
pass
def set_selected_track_next(self) -> None:
"""
Set currently-selected row on visible playlist tab as next track
"""
playlist_tab = self.active_tab()
selected_plr_ids = playlist_tab.get_selected_playlistrow_ids()
if len(selected_plr_ids) != 1:
log.error(f"set_next_track:_from_mm {selected_plr_ids=}")
return
self.set_next_plr_id(selected_plr_ids[0], playlist_tab)
def set_next_plr_id(
self, next_plr_id: Optional[int], playlist_tab: PlaylistTab
) -> None:
@ -1541,37 +1538,33 @@ class Window(QMainWindow, Ui_MainWindow):
- Populate info tabs
"""
with Session() as session:
# Update self.next_track PlaylistTrack structure
old_next_track = self.next_track
self.next_track = NextTrack()
if next_plr_id:
next_plr = session.get(PlaylistRows, next_plr_id)
if next_plr:
self.next_track.set_plr(session, next_plr)
return
# with Session() as session:
# # Update self.next_track PlaylistTrack structure
# self.next_track = NextTrack()
# if next_plr_id:
# next_plr = session.get(PlaylistRows, next_plr_id)
# if next_plr:
# self.next_track.set_plr(session, next_plr)
# self.signals.set_next_track_signal.emit(next_plr.playlist_id)
# Tell playlist tabs to update their 'next track' highlighting
# Args must both be ints, so use zero for no next track
self.signals.set_next_track_signal.emit(
old_next_track.plr_id, next_plr_id or 0
)
# # Update headers
# self.update_headers()
# Update headers
self.update_headers()
# TODO: reimlement
# # Set playlist tab colours
# self._set_next_track_playlist_tab_colours(old_next_track)
# Set playlist tab colours
self._set_next_track_playlist_tab_colours(old_next_track)
if next_plr_id:
# Populate 'info' tabs with Wikipedia info, but queue it
# because it isn't quick
if self.next_track.title:
QTimer.singleShot(
0,
lambda: self.tabInfolist.open_in_wikipedia(
self.next_track.title
),
)
# if next_plr_id:
# # Populate 'info' tabs with Wikipedia info, but queue it
# # because it isn't quick
# if self.next_track.title:
# QTimer.singleShot(
# 0,
# lambda: self.tabInfolist.open_in_wikipedia(
# self.next_track.title
# ),
# )
def _set_next_track_playlist_tab_colours(
self, old_next_track: Optional[PlaylistTrack]

View File

@ -101,8 +101,11 @@ class PlaylistModel(QAbstractTableModel):
self.playlist_rows: dict[int, PlaylistRowData] = {}
self.signals = MusicMusterSignals()
self.signals.add_track_to_playlist_signal.connect(self.add_track)
self.signals.add_track_to_header_signal.connect(self.add_track_to_header)
self.signals.add_track_to_playlist_signal.connect(self.add_track)
self.current_track = CurrentTrack()
self.next_track = NextTrack()
with Session() as session:
self.refresh_data(session)
@ -190,6 +193,12 @@ class PlaylistModel(QAbstractTableModel):
# Unreadable track file
if file_is_unreadable(prd.path):
return QBrush(QColor(Config.COLOUR_UNREADABLE))
# Current track
if prd.plrid == self.current_track.plr_id:
return QBrush(QColor(Config.COLOUR_CURRENT_PLAYLIST))
# Next track
if prd.plrid == self.next_track.plr_id:
return QBrush(QColor(Config.COLOUR_NEXT_PLAYLIST))
# Individual cell colouring
if column == Col.START_GAP.value:
@ -514,6 +523,28 @@ class PlaylistModel(QAbstractTableModel):
return len(self.playlist_rows)
def set_next_track(self, row_number: int) -> None:
"""
Update display if necessary
"""
# Update self.next_track PlaylistTrack structure
with Session() as session:
self.next_track = NextTrack()
try:
plrid = self.playlist_rows[row_number].plrid
except IndexError:
log.error(
f"playlistmodel.set_next_track({row_number=}, "
f"{self.playlist_id=}"
)
return
plr = session.get(PlaylistRows, plrid)
if plr:
self.next_track.set_plr(session, plr)
self.signals.next_track_changed_signal.emit()
self.invalidate_row(row_number)
def setData(
self, index: QModelIndex, value: QVariant, role: int = Qt.ItemDataRole.EditRole
) -> bool:

View File

@ -543,12 +543,12 @@ class PlaylistTab(QTableView):
# else:
# return self.rowCount()
# def get_selected_playlistrow_ids(self) -> list:
# """
# Return a list of PlaylistRow ids of the selected rows
# """
def get_selected_playlistrow_ids(self) -> list:
"""
Return a list of PlaylistRow ids of the selected rows
"""
# return [self._get_row_plr_id(a) for a in self._get_selected_rows()]
return [self._get_row_plr_id(a) for a in self._get_selected_rows()]
# def get_selected_playlistrows(self, session: scoped_session) -> List[PlaylistRows]:
# """
@ -1019,6 +1019,18 @@ class PlaylistTab(QTableView):
# # Reset selection mode
# self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
def set_row_as_next_track(self) -> None:
"""
Set selected row as next track
"""
selected_row = self._get_selected_row()
if selected_row is None:
return
model = cast(PlaylistModel, self.model())
model.set_next_track(selected_row)
self.clearSelection()
# def tab_visible(self) -> None:
# """Called when tab becomes visible"""
@ -1475,19 +1487,18 @@ class PlaylistTab(QTableView):
or None if none selected
"""
if not self.selectionModel().hasSelection():
return None
else:
return self.selectionModel().selectedRows()[0].row()
sm = self.selectionModel()
if sm:
if sm.hasSelection():
return sm.selectedIndexes()[0].row()
return None
def _get_selected_rows(self) -> List[int]:
"""Return a list of selected row numbers sorted by row"""
# Use a set to deduplicate result (a selected row will have all
# items in that row selected)
return sorted(
[row_number for row_number in set([a.row() for a in self.selectedItems()])]
)
return sorted(list(set([a.row() for a in self.selectedIndexes()])))
def _info_row(self, track_id: int) -> None:
"""Display popup with info re row"""