musicmuster refactor: signal next tracks, tab colouring
This commit is contained in:
parent
728feb1c8e
commit
9c66333729
@ -142,7 +142,7 @@ class CartButton(QPushButton):
|
|||||||
class PlaylistTrack:
|
class PlaylistTrack:
|
||||||
"""
|
"""
|
||||||
Used to provide a single reference point for specific playlist tracks,
|
Used to provide a single reference point for specific playlist tracks,
|
||||||
typicall the previous, current and next track.
|
typically the previous, current and next track.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
@ -257,7 +257,7 @@ class MusicMusterSignals(QObject):
|
|||||||
emit-a-signal-from-another-class-to-main-class
|
emit-a-signal-from-another-class-to-main-class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
update_row_note_signal = pyqtSignal(int)
|
set_next_track_signal = pyqtSignal(int, int)
|
||||||
|
|
||||||
|
|
||||||
class Window(QMainWindow, Ui_MainWindow):
|
class Window(QMainWindow, Ui_MainWindow):
|
||||||
@ -579,8 +579,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.actionSelect_previous_track.triggered.connect(
|
self.actionSelect_previous_track.triggered.connect(
|
||||||
self.select_previous_row)
|
self.select_previous_row)
|
||||||
self.actionMoveUnplayed.triggered.connect(self.move_unplayed)
|
self.actionMoveUnplayed.triggered.connect(self.move_unplayed)
|
||||||
self.actionSetNext.triggered.connect(
|
self.actionSetNext.triggered.connect(self.set_next_track_from_mm)
|
||||||
lambda: self.tabPlaylist.currentWidget().set_selected_as_next())
|
|
||||||
self.actionSkipToNext.triggered.connect(self.play_next)
|
self.actionSkipToNext.triggered.connect(self.play_next)
|
||||||
self.actionStop.triggered.connect(self.stop)
|
self.actionStop.triggered.connect(self.stop)
|
||||||
self.btnDrop3db.clicked.connect(self.drop3db)
|
self.btnDrop3db.clicked.connect(self.drop3db)
|
||||||
@ -1285,43 +1284,47 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
def resume(self) -> None:
|
def resume(self) -> None:
|
||||||
"""
|
"""
|
||||||
Resume playing stopped track
|
Resume playing last track. We may be playing the next track
|
||||||
|
or none; take care of both eventualities.
|
||||||
|
|
||||||
Actions required:
|
Actions required:
|
||||||
- Return if no saved position
|
- Return if no saved position
|
||||||
- Store saved position
|
- Resume last track
|
||||||
- Store next track
|
- If a track is playing, make that the next track
|
||||||
- Set previous track to be next track
|
|
||||||
- Call play_next() from saved position
|
|
||||||
- Reset next track
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Return if no saved position
|
# Return if no saved position
|
||||||
if not self.previous_track_position:
|
if not self.previous_track_position:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Note resume point
|
# Note any playing track as this will become the next track
|
||||||
resume_from = self.previous_track_position
|
playing_track = None
|
||||||
|
if self.current_track.track_id:
|
||||||
# Remember what was to have been the next track
|
playing_track = self.current_track
|
||||||
original_next_plr_id = self.next_track.plr_id
|
|
||||||
original_next_plr_playlist_tab = self.next_track.playlist_tab
|
|
||||||
|
|
||||||
with Session() as session:
|
with Session() as session:
|
||||||
# Set next track to be the last one played
|
# Set next plr to be track to resume
|
||||||
self.next_track = self.previous_track
|
plr_resume = session.get(PlaylistRows, self.previous_track.plr_id)
|
||||||
self.previous_track = PlaylistTrack()
|
if not plr_resume:
|
||||||
|
return
|
||||||
|
plr_tab_resume = self.previous_track.playlist_tab
|
||||||
|
if not plr_tab_resume:
|
||||||
|
return
|
||||||
|
|
||||||
# Resume last track
|
# Resume last track
|
||||||
self.play_next(resume_from)
|
self._set_next_plr(session, plr_resume, plr_tab_resume)
|
||||||
|
self.play_next(self.previous_track_position)
|
||||||
|
|
||||||
# Reset next track if there was one
|
# If a track was playing when we were called, get details to
|
||||||
if original_next_plr_id:
|
# set it as the next track
|
||||||
next_plr = session.get(PlaylistRows, original_next_plr_id)
|
if playing_track:
|
||||||
if not next_plr or not original_next_plr_playlist_tab:
|
plr_next = session.get(PlaylistRows, playing_track.plr_id)
|
||||||
|
if not plr_next:
|
||||||
return
|
return
|
||||||
self.this_is_the_next_playlist_row(
|
plr_tab_next = playing_track.playlist_tab
|
||||||
session, next_plr, original_next_plr_playlist_tab)
|
if not plr_tab_next:
|
||||||
|
return
|
||||||
|
self._set_next_plr(session, plr_next, plr_tab_next)
|
||||||
|
|
||||||
def save_as_template(self) -> None:
|
def save_as_template(self) -> None:
|
||||||
"""Save current playlist as template"""
|
"""Save current playlist as template"""
|
||||||
@ -1494,57 +1497,58 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
# May also be called when last tab is closed
|
# May also be called when last tab is closed
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def this_is_the_next_playlist_row(
|
def set_next_track_from_playlist(self, playlist_tab: PlaylistTab,
|
||||||
self, session: scoped_session, plr: PlaylistRows,
|
next_plr_id: int) -> None:
|
||||||
next_track_playlist_tab: PlaylistTab) -> None:
|
|
||||||
"""
|
"""
|
||||||
This is notification from a playlist tab that it holds the next
|
Called from playlist tab to notify us of next track
|
||||||
playlist row to be played.
|
|
||||||
|
|
||||||
Actions required:
|
|
||||||
- Clear next track if on other tab
|
|
||||||
- Reset tab colour if on other tab
|
|
||||||
- Note next playlist tab
|
|
||||||
- Set next next_track_playlist_tab tab colour
|
|
||||||
- Note next track
|
|
||||||
- Update headers
|
|
||||||
- Populate ‘info’ tabs
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if plr.track_id is None:
|
with Session() as session:
|
||||||
|
next_plr = session.get(PlaylistRows, next_plr_id)
|
||||||
|
if not next_plr:
|
||||||
return
|
return
|
||||||
|
|
||||||
# If we already have a next tab lined up and it's neither
|
self._set_next_plr(session, next_plr, playlist_tab)
|
||||||
# the "new" next tab nor the current track tab then we need
|
|
||||||
# to reset the tab colour.
|
|
||||||
if (
|
|
||||||
self.next_track.playlist_tab and
|
|
||||||
self.next_track.playlist_tab != next_track_playlist_tab and
|
|
||||||
self.next_track.playlist_tab != self.current_track.playlist_tab
|
|
||||||
):
|
|
||||||
self.set_tab_colour(self.next_track.playlist_tab,
|
|
||||||
QColor(Config.COLOUR_NORMAL_TAB))
|
|
||||||
|
|
||||||
# Discard now-incorrect next_track PlaylistTrack and tell
|
def set_next_track_from_mm(self) -> None:
|
||||||
# playlist_tab too
|
"""
|
||||||
self.next_track.playlist_tab.clear_next()
|
Set currently-selected row on visible playlist tab as next track
|
||||||
self.clear_next()
|
|
||||||
|
|
||||||
# Populate self.next_track
|
Actions required:
|
||||||
self.next_track.set_plr(session, plr, next_track_playlist_tab)
|
- Update self.next_track PlaylistTrack structure
|
||||||
if self.next_track.playlist_tab:
|
- Set playlist tab colours
|
||||||
if self.current_track.playlist_tab != self.next_track.playlist_tab:
|
- Tell playlist tabs to update their 'next track' highlighting
|
||||||
self.set_tab_colour(self.next_track.playlist_tab,
|
- Update headers
|
||||||
QColor(Config.COLOUR_NEXT_TAB))
|
- Populate ‘info’ tabs
|
||||||
|
"""
|
||||||
|
|
||||||
# Populate footer if we're not currently playing
|
with Session() as session:
|
||||||
if not self.playing and self.next_track.track_id:
|
playlist_tab = self.visible_playlist_tab()
|
||||||
self.label_track_length.setText(
|
selected_plrs = playlist_tab.get_selected_playlistrows(session)
|
||||||
helpers.ms_to_mmss(self.next_track.duration)
|
if len(selected_plrs) != 1:
|
||||||
)
|
log.error(f"set_next_track:_from_mm {selected_plrs=}")
|
||||||
self.label_fade_length.setText(helpers.ms_to_mmss(
|
return
|
||||||
self.next_track.fade_length))
|
next_plr = selected_plrs[0]
|
||||||
|
self._set_next_plr(session, next_plr, playlist_tab)
|
||||||
|
|
||||||
|
def _set_next_plr(self, session: scoped_session,
|
||||||
|
next_plr: PlaylistRows,
|
||||||
|
playlist_tab: PlaylistTab) -> None:
|
||||||
|
"""
|
||||||
|
Set next_plr as the next track to play
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Build PlaylistTrack structure for new next track
|
||||||
|
old_next_track = self.next_track
|
||||||
|
self.next_track = PlaylistTrack()
|
||||||
|
self.next_track.set_plr(session, next_plr, playlist_tab)
|
||||||
|
|
||||||
|
# Set playlist tab colours
|
||||||
|
self._set_next_track_playlist_tab_colours(old_next_track)
|
||||||
|
|
||||||
|
# Tell playlist tabs to update themselves
|
||||||
|
self.signals.set_next_track_signal.emit(old_next_track.plr_id,
|
||||||
|
next_plr.id)
|
||||||
|
|
||||||
# Update headers
|
# Update headers
|
||||||
self.update_headers()
|
self.update_headers()
|
||||||
@ -1556,6 +1560,40 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
1, lambda: self.tabInfolist.open_in_wikipedia(track_title)
|
1, lambda: self.tabInfolist.open_in_wikipedia(track_title)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _set_next_track_playlist_tab_colours(
|
||||||
|
self, old_next_track: Optional[PlaylistTrack]) -> None:
|
||||||
|
"""
|
||||||
|
Set playlist tab colour for next track. self.next_track needs
|
||||||
|
to be set before calling.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# If the original next playlist tab isn't the same as the
|
||||||
|
# new one or the current track, it needs its colour reset.
|
||||||
|
if (
|
||||||
|
old_next_track and
|
||||||
|
old_next_track.playlist_tab and
|
||||||
|
old_next_track.playlist_tab not in [
|
||||||
|
self.next_track.playlist_tab,
|
||||||
|
self.current_track.playlist_tab
|
||||||
|
]):
|
||||||
|
self.set_tab_colour(old_next_track.playlist_tab,
|
||||||
|
QColor(Config.COLOUR_NORMAL_TAB))
|
||||||
|
# If the new next playlist tab isn't the same as the
|
||||||
|
# old one or the current track, it needs its colour set.
|
||||||
|
if old_next_track:
|
||||||
|
old_tab = old_next_track.playlist_tab
|
||||||
|
else:
|
||||||
|
old_tab = None
|
||||||
|
if (
|
||||||
|
self.next_track and
|
||||||
|
self.next_track.playlist_tab and
|
||||||
|
self.next_track.playlist_tab not in [
|
||||||
|
old_tab,
|
||||||
|
self.current_track.playlist_tab
|
||||||
|
]):
|
||||||
|
self.set_tab_colour(self.next_track.playlist_tab,
|
||||||
|
QColor(Config.COLOUR_NEXT_TAB))
|
||||||
|
|
||||||
def tick(self) -> None:
|
def tick(self) -> None:
|
||||||
"""
|
"""
|
||||||
Carry out clock tick actions.
|
Carry out clock tick actions.
|
||||||
|
|||||||
@ -191,13 +191,14 @@ class PlaylistTab(QTableWidget):
|
|||||||
# Call self.eventFilter() for events
|
# Call self.eventFilter() for events
|
||||||
self.viewport().installEventFilter(self)
|
self.viewport().installEventFilter(self)
|
||||||
|
|
||||||
self.itemSelectionChanged.connect(self._select_event)
|
|
||||||
|
|
||||||
self.search_text: str = ""
|
self.search_text: str = ""
|
||||||
self.edit_cell_type: Optional[int]
|
self.edit_cell_type: Optional[int]
|
||||||
self.selecting_in_progress = False
|
self.selecting_in_progress = False
|
||||||
|
|
||||||
# Connect signals
|
# Connect signals
|
||||||
self.horizontalHeader().sectionResized.connect(self._column_resize)
|
self.horizontalHeader().sectionResized.connect(self._column_resize)
|
||||||
|
self.itemSelectionChanged.connect(self._select_event)
|
||||||
|
self.signals.set_next_track_signal.connect(self._reset_next)
|
||||||
|
|
||||||
# Load playlist rows
|
# Load playlist rows
|
||||||
self.populate_display(session, self.playlist_id)
|
self.populate_display(session, self.playlist_id)
|
||||||
@ -647,7 +648,8 @@ class PlaylistTab(QTableWidget):
|
|||||||
# Set next track
|
# Set next track
|
||||||
next_row = self._find_next_track_row(session, current_row + 1)
|
next_row = self._find_next_track_row(session, current_row + 1)
|
||||||
if next_row:
|
if next_row:
|
||||||
self._set_next(session, next_row)
|
self.musicmuster.set_next_track_from_playlist(
|
||||||
|
self, self._get_row_plr_id(next_row))
|
||||||
|
|
||||||
# Display row as current track
|
# Display row as current track
|
||||||
self._set_row_colour_current(current_row)
|
self._set_row_colour_current(current_row)
|
||||||
@ -732,7 +734,6 @@ class PlaylistTab(QTableWidget):
|
|||||||
row_number = self._get_next_track_row_number()
|
row_number = self._get_next_track_row_number()
|
||||||
if not row_number:
|
if not row_number:
|
||||||
return
|
return
|
||||||
self.musicmuster.clear_next()
|
|
||||||
self._set_row_colour_default(row_number)
|
self._set_row_colour_default(row_number)
|
||||||
self.clear_selection()
|
self.clear_selection()
|
||||||
|
|
||||||
@ -868,14 +869,6 @@ class PlaylistTab(QTableWidget):
|
|||||||
|
|
||||||
self.selectRow(row_number)
|
self.selectRow(row_number)
|
||||||
|
|
||||||
def set_selected_as_next(self) -> None:
|
|
||||||
"""Sets the select track as next to play"""
|
|
||||||
|
|
||||||
row_number = self._get_selected_row()
|
|
||||||
if row_number is not None:
|
|
||||||
with Session() as session:
|
|
||||||
self._set_next(session, row_number)
|
|
||||||
|
|
||||||
def tab_visible(self) -> None:
|
def tab_visible(self) -> None:
|
||||||
"""Called when tab becomes visible"""
|
"""Called when tab becomes visible"""
|
||||||
|
|
||||||
@ -890,7 +883,6 @@ class PlaylistTab(QTableWidget):
|
|||||||
def _add_track(self, row_number: int) -> None:
|
def _add_track(self, row_number: int) -> None:
|
||||||
"""Add a track to a section header making it a normal track row"""
|
"""Add a track to a section header making it a normal track row"""
|
||||||
|
|
||||||
print(f"_add_track({row_number=})")
|
|
||||||
with Session() as session:
|
with Session() as session:
|
||||||
# Add track to playlist row
|
# Add track to playlist row
|
||||||
plr = self._get_row_plr(session, row_number)
|
plr = self._get_row_plr(session, row_number)
|
||||||
@ -1709,54 +1701,45 @@ class PlaylistTab(QTableWidget):
|
|||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
||||||
def _set_next(self, session: scoped_session, row_number: int) -> None:
|
def _reset_next(self, old_plrid: int, new_plrid: int) -> None:
|
||||||
"""
|
"""
|
||||||
Set passed row as next playlist row to play.
|
Called when set_next_track_signal signal received.
|
||||||
|
|
||||||
Actions required:
|
Actions required:
|
||||||
- Check row has a track
|
- If old_plrid points to this playlist:
|
||||||
- Check track is readable
|
- Remove existing next track
|
||||||
- Notify musicmuster
|
- If new_plrid points to this playlist:
|
||||||
|
- Set track as next
|
||||||
- Display row as next track
|
- Display row as next track
|
||||||
- Update start/stop times
|
- Update start/stop times
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Check row has a track
|
with Session() as session:
|
||||||
track_id = self._get_row_track_id(row_number)
|
# Get plrs
|
||||||
if not track_id:
|
old_plr = new_plr = None
|
||||||
log.error(
|
if old_plrid:
|
||||||
f"playlists._set_next({row_number=}) has no track associated"
|
old_plr = session.get(PlaylistRows, old_plrid)
|
||||||
)
|
if not new_plrid:
|
||||||
|
log.error(f"_reset_next called with {new_plrid=}")
|
||||||
|
return
|
||||||
|
new_plr = session.get(PlaylistRows, new_plrid)
|
||||||
|
if not new_plr:
|
||||||
|
log.error(f"_reset_next({new_plrid=}): plr not found")
|
||||||
return
|
return
|
||||||
|
|
||||||
track = session.get(Tracks, track_id)
|
# Unmark next track
|
||||||
if not track:
|
if old_plr and old_plr.playlist_id == self.playlist_id:
|
||||||
log.error(f"playlists._set_next({row_number=}): Track not found")
|
self._set_row_colour_default(old_plr.row_number)
|
||||||
return
|
|
||||||
|
|
||||||
# Check track is readable
|
# Mark next track
|
||||||
if file_is_unreadable(track.path):
|
if new_plr and new_plr.playlist_id == self.playlist_id:
|
||||||
return None
|
self._set_row_colour_next(new_plr.row_number)
|
||||||
|
|
||||||
# Clear any existing next track
|
|
||||||
next_track_row = self._get_next_track_row_number()
|
|
||||||
if next_track_row:
|
|
||||||
self._set_row_colour_default(next_track_row)
|
|
||||||
|
|
||||||
# Notify musicmuster
|
|
||||||
plr = self._get_row_plr(session, row_number)
|
|
||||||
if not plr:
|
|
||||||
log.debug(f"playists._set_next({row_number=}) can't retrieve plr")
|
|
||||||
else:
|
|
||||||
self.musicmuster.this_is_the_next_playlist_row(session, plr, self)
|
|
||||||
|
|
||||||
# Display row as next track
|
|
||||||
self._set_row_colour_next(row_number)
|
|
||||||
|
|
||||||
# Update start/stop times
|
# Update start/stop times
|
||||||
self.clear_selection()
|
|
||||||
self._update_start_end_times(session)
|
self._update_start_end_times(session)
|
||||||
|
|
||||||
|
self.clear_selection()
|
||||||
|
|
||||||
def _set_played_row(self, session: scoped_session,
|
def _set_played_row(self, session: scoped_session,
|
||||||
row_number: int) -> None:
|
row_number: int) -> None:
|
||||||
"""Mark this row as played"""
|
"""Mark this row as played"""
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user