diff --git a/app/classes.py b/app/classes.py index 8bdc796..13fd882 100644 --- a/app/classes.py +++ b/app/classes.py @@ -282,7 +282,7 @@ class MusicMusterSignals(QObject): signal_next_track_changed = pyqtSignal() # Emited when a track starts playing - signal_track_started = pyqtSignal(TrackAndPlaylist) + signal_track_started = pyqtSignal() # Used by model to signal spanning of cells to playlist for headers span_cells_signal = pyqtSignal(int, int, int, int, int) diff --git a/app/log.py b/app/log.py index 836b2ca..94d9942 100644 --- a/app/log.py +++ b/app/log.py @@ -86,6 +86,9 @@ def handle_exception(exc_type, exc_value, exc_traceback): # Navigate to the inner stack frame tb = exc_traceback + if not tb: + log.error(f"handle_excption({exc_type=}, {exc_value=}, {exc_traceback=}") + return while tb.tb_next: tb = tb.tb_next diff --git a/app/musicmuster.py b/app/musicmuster.py index 9f9db7e..d9183ee 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -1255,7 +1255,7 @@ class Window(QMainWindow): return # Don't allow window to close when a track is playing - if self.track_sequence.current and self.track_sequence.current.is_playing(): + if self.track_sequence.current and self.track_sequence.current.music.is_playing(): event.ignore() helpers.show_warning( self, "Track playing", "Can't close application while track is playing" @@ -2195,12 +2195,7 @@ class Window(QMainWindow): ds.playdates_update(self.track_sequence.current.track_id) # Notify others - self.signals.signal_track_started.emit( - TrackAndPlaylist( - self.track_sequence.current.playlist_id, - self.track_sequence.current.track_id, - ) - ) + self.signals.signal_track_started.emit() # Update headers self.update_headers() @@ -2634,7 +2629,7 @@ class Window(QMainWindow): """ # If track is playing, update track clocks time and colours - if self.track_sequence.current and self.track_sequence.current.is_playing(): + if self.track_sequence.current and self.track_sequence.current.music.is_playing(): # Elapsed time self.header_section.label_elapsed_timer.setText( helpers.ms_to_mmss(self.track_sequence.current.time_playing()) diff --git a/app/playlistmodel.py b/app/playlistmodel.py index 055b72b..fcc5b8d 100644 --- a/app/playlistmodel.py +++ b/app/playlistmodel.py @@ -3,7 +3,7 @@ from __future__ import annotations from operator import attrgetter from random import shuffle -from typing import cast, Optional +from typing import cast import datetime as dt import re @@ -159,7 +159,9 @@ class PlaylistModel(QAbstractTableModel): return if not self.selected_rows: - raise ApplicationError("Add track to header but no row selected") + self.signals.show_warning_signal.emit( + "Add track to header", "Add track to header but no row selected" + ) if len(self.selected_rows) > 1: self.signals.show_warning_signal.emit( @@ -170,7 +172,7 @@ class PlaylistModel(QAbstractTableModel): selected_row = self.selected_rows[0] if selected_row.path: self.signals.show_warning_signal.emit( - "Add track to header", "Select header to add track to" + "Add track to header", "Select a header to add track to" ) return @@ -247,10 +249,9 @@ class PlaylistModel(QAbstractTableModel): return len(Col) # @log_call - def track_started(self, play_track: TrackAndPlaylist) -> None: + def track_started(self) -> None: """ - Notification from musicmuster that the current track has just - started playing + Handle signal_track_started signal. Actions required: - sanity check @@ -289,18 +290,16 @@ class PlaylistModel(QAbstractTableModel): ds.playdates_update(track_id) # Mark track as played in playlist - playlist_dto.played = True + self.playlist_rows[row_number].played = True # Update colour and times for current row - roles_to_invalidate = [Qt.ItemDataRole.DisplayRole] - self.invalidate_row(row_number, roles_to_invalidate) + roles = [Qt.ItemDataRole.DisplayRole] + self.invalidate_row(row_number, roles) # Update previous row in case we're hiding played rows if self.track_sequence.previous and self.track_sequence.previous.row_number: # only invalidate required roles - self.invalidate_row( - self.track_sequence.previous.row_number, roles_to_invalidate - ) + self.invalidate_row(self.track_sequence.previous.row_number, roles) # Update all other track times self.update_track_times() @@ -566,7 +565,7 @@ class PlaylistModel(QAbstractTableModel): return self.playlist_rows[row_number] # @log_call - def get_row_track_id(self, row_number: int) -> Optional[int]: + def get_row_track_id(self, row_number: int) -> int | None: """ Return id of track associated with row or None if no track associated """ @@ -776,7 +775,7 @@ class PlaylistModel(QAbstractTableModel): return self.playlist_rows[row_number].played - def is_track_in_playlist(self, track_id: int) -> Optional[PlaylistRow]: + def is_track_in_playlist(self, track_id: int) -> PlaylistRow | None: """ If this track_id is in the playlist, return the RowAndTrack object else return None @@ -1300,7 +1299,7 @@ class PlaylistModel(QAbstractTableModel): if plr.track_id is None: raise ApplicationError(f"set_next_row: no track_id ({plr=})") - old_next_row: Optional[int] = None + old_next_row: int | None = None if self.track_sequence.next: old_next_row = self.track_sequence.next.row_number @@ -1548,24 +1547,42 @@ class PlaylistModel(QAbstractTableModel): continue # Set start time for next row if we have a current track - if ( - row_number == next_track_row - and self.track_sequence.current - and self.track_sequence.current.end_time - ): - next_start_time = plr.set_forecast_start_time( - update_rows, self.track_sequence.current.end_time - ) + if (current_track_row_number and row_number == next_track_row): + plr = self.playlist_rows[row_number] + next_start_time = self.playlist_rows[current_track_row_number].forecast_end_time + if next_start_time != plr.forecast_start_time: + plr.forecast_start_time = next_start_time + update_rows.append(row_number) + + # Get next start time, which is end time for this track + if next_start_time: + next_start_time = self.get_end_time(current_track_row_number, next_start_time) + if next_start_time != plr.forecast_end_time: + plr.forecast_end_time = next_start_time + update_rows.append(current_track_row_number) continue # If we're between the current and next row, zero out # times - if (current_track_row or row_count) < row_number < (next_track_row or 0): - plr.set_forecast_start_time(update_rows, None) + if (current_track_row_number or row_count) < row_number < (next_track_row or 0): + plr.forecast_start_time = plr.forecast_end_time = None + update_rows.append(row_number) continue # Set start/end - plr.forecast_start_time = next_start_time + if not next_start_time: + continue + plr = self.playlist_rows[row_number] + if next_start_time != plr.forecast_start_time: + plr.forecast_start_time = next_start_time + update_rows.append(row_number) + + # Get next start time, which is end time for this track + next_start_time = self.get_end_time(row_number, next_start_time) + if next_start_time != plr.forecast_end_time: + plr.forecast_end_time = next_start_time + update_rows.append(row_number) + continue # Update start/stop times of rows that have changed for updated_row in update_rows: diff --git a/app/playlistrow.py b/app/playlistrow.py index dfaed3b..eef378b 100644 --- a/app/playlistrow.py +++ b/app/playlistrow.py @@ -264,39 +264,6 @@ class PlaylistRow: milliseconds=update_graph_at_ms ) - def set_forecast_start_time( - self, modified_rows: list[int], start: dt.datetime | None - ) -> dt.datetime | None: - """ - Set forecast start time for this row - - Update passed modified rows list if we changed the row. - - Return new start time - """ - - changed = False - - if self.forecast_start_time != start: - self.forecast_start_time = start - changed = True - if start is None: - if self.forecast_end_time is not None: - self.forecast_end_time = None - changed = True - new_start_time = None - else: - end_time = start + dt.timedelta(milliseconds=self.duration) - new_start_time = end_time - if self.forecast_end_time != end_time: - self.forecast_end_time = end_time - changed = True - - if changed and self.row_number not in modified_rows: - modified_rows.append(self.row_number) - - return new_start_time - def stop(self, fade_seconds: int = 0) -> None: """ Stop this track playing diff --git a/app/playlists.py b/app/playlists.py index 6e795b0..901357f 100644 --- a/app/playlists.py +++ b/app/playlists.py @@ -729,17 +729,18 @@ class PlaylistTab(QTableView): cb.setText(track_path, mode=cb.Mode.Clipboard) # @log_call - def track_started(self, play_track: TrackAndPlaylist) -> None: + def track_started(self) -> None: """ Called when track starts playing """ - if play_track.playlist_id != self.playlist_id: + if self.track_sequence.current is None: + return + + if self.track_sequence.current.playlist_id != self.playlist_id: # Not for us return - # TODO - via signal - # self.get_base_model().current_track_started() # Scroll to current section if hide mode is by section if ( self.musicmuster.hide_played_tracks