diff --git a/app/models.py b/app/models.py index 8ccd0c8..06d560b 100644 --- a/app/models.py +++ b/app/models.py @@ -93,35 +93,6 @@ class NoteColours(Base): f"colour={self.colour}>" ) - # def __init__( - # self, session: Session, substring: str, colour: str, - # enabled: bool = True, is_regex: bool = False, - # is_casesensitive: bool = False, order: int = 0) -> None: - # self.substring = substring - # self.colour = colour - # self.enabled = enabled - # self.is_regex = is_regex - # self.is_casesensitive = is_casesensitive - # self.order = order - # - # session.add(self) - # session.flush() - # - # @classmethod - # def get_all(cls, session: Session) -> - # Optional[List["NoteColours"]]: - # """Return all records""" - # - # return session.query(cls).all() - # - # @classmethod - # def get_by_id(cls, session: Session, note_id: int) -> \ - # Optional["NoteColours"]: - # """Return record identified by id, or None if not found""" - # - # return session.query(NoteColours).filter( - # NoteColours.id == note_id).first() - @staticmethod def get_colour(session: Session, text: str) -> Optional[str]: """ diff --git a/app/musicmuster.py b/app/musicmuster.py index d2f9c2a..af82c26 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -123,6 +123,12 @@ class TrackData: self.path = track.path self.mtime = track.mtime + def __repr__(self) -> str: + return ( + f"" + ) + class Window(QMainWindow, Ui_MainWindow): def __init__(self, parent=None) -> None: @@ -140,6 +146,7 @@ class Window(QMainWindow, Ui_MainWindow): self.next_track: Optional[TrackData] = None self.next_track_playlist_tab: Optional[PlaylistTab] = None self.previous_track: Optional[TrackData] = None + self.previous_track_playlist_tab: Optional[PlaylistTab] = None self.previous_track_position: Optional[int] = None self.selected_plrs = None @@ -410,6 +417,7 @@ class Window(QMainWindow, Ui_MainWindow): self.actionOpenPlaylist.triggered.connect(self.open_playlist) self.actionPaste.triggered.connect(self.paste_rows) self.actionPlay_next.triggered.connect(self.play_next) + self.actionResume.triggered.connect(self.resume) self.actionSave_as_template.triggered.connect(self.save_as_template) self.actionSearch.triggered.connect(self.search_playlist) self.actionSelect_next_track.triggered.connect(self.select_next_row) @@ -563,6 +571,7 @@ class Window(QMainWindow, Ui_MainWindow): # Tell playlist_tab track has finished and # reset current playlist_tab if self.current_track_playlist_tab: + self.previous_track_playlist_tab = self.current_track_playlist_tab self.current_track_playlist_tab.play_stopped() self.current_track_playlist_tab = None @@ -969,9 +978,9 @@ class Window(QMainWindow, Ui_MainWindow): # Reset so rows can't be repasted self.selected_plrs = None - def play_next(self) -> None: + def play_next(self, position: Optional[float] = None) -> None: """ - Play next track. + Play next track, optionally from passed position. Actions required: - If there is no next track set, return. @@ -1020,7 +1029,7 @@ class Window(QMainWindow, Ui_MainWindow): # Play (new) current track start_at = datetime.now() - self.music.play(self.current_track.path) + self.music.play(self.current_track.path, position) # Tell database to record it as played Playdates(session, self.current_track.id) @@ -1052,6 +1061,45 @@ class Window(QMainWindow, Ui_MainWindow): self.label_end_time.setText( self.current_track_end_time.strftime(Config.TRACK_TIME_FORMAT)) + def resume(self) -> None: + """ + Resume playing stopped track + + Actions required: + - Return if no saved position + - Store saved position + - Store next track + - Set previous track to be next track + - Call play_next() from saved position + - Reset next track + """ + + # Return if no saved position + if not self.previous_track_position: + return + + # Note resume point + resume_from = self.previous_track_position + + # Remember current next track + original_next_track = self.next_track + original_next_track_playlist_tab = self.next_track_playlist_tab + + with Session() as session: + # Set last track to be next track + self.this_is_the_next_track(session, + self.previous_track_playlist_tab, + self.previous_track) + + # Resume last track + self.play_next(resume_from) + + # Reset next track if there was one + if original_next_track: + self.this_is_the_next_track(session, + original_next_track_playlist_tab, + original_next_track) + def save_as_template(self) -> None: """Save current playlist as template""" @@ -1148,7 +1196,7 @@ class Window(QMainWindow, Ui_MainWindow): def show_current(self) -> None: """Scroll to show current track""" - log.debug(f"KAE: musicmuster.show_current()") + log.debug("KAE: musicmuster.show_current()") if self.current_track_playlist_tab != self.visible_playlist_tab(): self.tabPlaylist.setCurrentWidget(self.current_track_playlist_tab) self.tabPlaylist.currentWidget().scroll_current_to_top() @@ -1156,7 +1204,7 @@ class Window(QMainWindow, Ui_MainWindow): def show_next(self) -> None: """Scroll to show next track""" - log.debug(f"KAE: musicmuster.show_next()") + log.debug("KAE: musicmuster.show_next()") if self.next_track_playlist_tab != self.visible_playlist_tab(): self.tabPlaylist.setCurrentWidget(self.next_track_playlist_tab) self.tabPlaylist.currentWidget().scroll_next_to_top() @@ -1252,8 +1300,8 @@ class Window(QMainWindow, Ui_MainWindow): self.next_track_playlist_tab, QColor(Config.COLOUR_NORMAL_TAB)) - # Note next playlist tab - self.next_track_playlist_tab = playlist_tab + # Note next playlist tab + self.next_track_playlist_tab = playlist_tab # Set next playlist_tab tab colour if it isn't the # currently-playing tab diff --git a/app/ui/main_window.ui b/app/ui/main_window.ui index a1fc471..9e2c7b5 100644 --- a/app/ui/main_window.ui +++ b/app/ui/main_window.ui @@ -854,6 +854,7 @@ padding-left: 8px; + @@ -1197,6 +1198,14 @@ padding-left: 8px; Ctrl+V + + + Resume + + + Ctrl+R + + diff --git a/app/ui/main_window_ui.py b/app/ui/main_window_ui.py index 49ffd97..7338d49 100644 --- a/app/ui/main_window_ui.py +++ b/app/ui/main_window_ui.py @@ -503,6 +503,8 @@ class Ui_MainWindow(object): self.actionMark_for_moving.setObjectName("actionMark_for_moving") self.actionPaste = QtWidgets.QAction(MainWindow) self.actionPaste.setObjectName("actionPaste") + self.actionResume = QtWidgets.QAction(MainWindow) + self.actionResume.setObjectName("actionResume") self.menuFile.addAction(self.actionNewPlaylist) self.menuFile.addAction(self.actionOpenPlaylist) self.menuFile.addAction(self.actionClosePlaylist) @@ -522,6 +524,7 @@ class Ui_MainWindow(object): self.menuPlaylist.addAction(self.actionPlay_next) self.menuPlaylist.addAction(self.actionFade) self.menuPlaylist.addAction(self.actionStop) + self.menuPlaylist.addAction(self.actionResume) self.menuPlaylist.addSeparator() self.menuPlaylist.addAction(self.actionSkipToNext) self.menuPlaylist.addSeparator() @@ -646,5 +649,7 @@ class Ui_MainWindow(object): self.actionMark_for_moving.setShortcut(_translate("MainWindow", "Ctrl+C")) self.actionPaste.setText(_translate("MainWindow", "Paste")) self.actionPaste.setShortcut(_translate("MainWindow", "Ctrl+V")) + self.actionResume.setText(_translate("MainWindow", "Resume")) + self.actionResume.setShortcut(_translate("MainWindow", "Ctrl+R")) from infotabs import InfoTabs import icons_rc