Maintain track headers when changing playlists

This commit is contained in:
Keith Edmunds 2021-04-25 00:04:01 +01:00
parent d157dbd7c0
commit b2fe5f6f38
2 changed files with 48 additions and 43 deletions

View File

@ -50,9 +50,9 @@ class Window(QMainWindow, Ui_MainWindow):
# Hard code to the first playlist for now # Hard code to the first playlist for now
# TODO # TODO
if self.playlist.load_playlist(1): self.playlist.load_playlist(1)
self.update_headers() self.update_headers()
self.enable_play_next_controls() self.enable_play_next_controls()
self.plLabel = QLabel(f"Playlist: {self.playlist.playlist_name}") self.plLabel = QLabel(f"Playlist: {self.playlist.playlist_name}")
self.statusbar.addPermanentWidget(self.plLabel) self.statusbar.addPermanentWidget(self.plLabel)

View File

@ -17,6 +17,7 @@ from PyQt5.QtWidgets import (
import helpers import helpers
import music import music
import os
from config import Config from config import Config
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -25,7 +26,6 @@ from model import Notes, Playdates, Playlists, PlaylistTracks, Settings, Tracks
from ui.dlg_search_database_ui import Ui_Dialog from ui.dlg_search_database_ui import Ui_Dialog
from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist
class Playlist(QTableWidget): class Playlist(QTableWidget):
# Column names # Column names
COL_INDEX = 0 COL_INDEX = 0
@ -364,6 +364,12 @@ class Playlist(QTableWidget):
def calculate_next_start_time(self, row, start): def calculate_next_start_time(self, row, start):
"Return this row's end time given its start time" "Return this row's end time given its start time"
if start is None:
return None
if row is None:
DEBUG("calculate_next_start_time() called with row=None")
return None
duration = Tracks.get_duration( duration = Tracks.get_duration(
int(self.item(row, self.COL_INDEX).text())) int(self.item(row, self.COL_INDEX).text()))
return start + timedelta(milliseconds=duration) return start + timedelta(milliseconds=duration)
@ -387,8 +393,6 @@ class Playlist(QTableWidget):
Load tracks and notes from playlist id. Load tracks and notes from playlist id.
Set first track as next track to play. Set first track as next track to play.
Return True if successful else False.
""" """
DEBUG(f"load_playlist(plid={plid})") DEBUG(f"load_playlist(plid={plid})")
@ -416,22 +420,36 @@ class Playlist(QTableWidget):
for item in sorted(data, key=lambda x: x[0]): for item in sorted(data, key=lambda x: x[0]):
self.add_to_playlist(item[1], repaint=False) self.add_to_playlist(item[1], repaint=False)
# Set the first non-notes row as next track to play # If this is not the first playlist loaded, we may already have
notes_rows = self.meta_get_notes() # a next track set in which case don't change it. Otherwise, set
for row in range(self.rowCount()): # the first non-notes row as next track to play.
if row in notes_rows: if not self.next_track:
continue notes_rows = self.meta_get_notes()
self.meta_set_next(row) for row in range(self.rowCount()):
self.tracks_changed() if row in notes_rows:
return True continue
self.cue_next_track(row)
break
return False # Scroll to top
scroll_to = self.item(0, self.COL_INDEX)
self.scrollToItem(scroll_to, QAbstractItemView.PositionAtTop)
def meta_clear(self, row): def meta_clear(self, row):
"Clear metadata for row" "Clear metadata for row"
self.meta_set(row, None) self.meta_set(row, None)
def meta_clear_current(self):
"""
Clear current row if there is one. There may not be if
we've changed playlists
"""
current_row = self.meta_get_current()
if current_row:
self.meta_clear(current_row)
def meta_find(self, metadata, one=True): def meta_find(self, metadata, one=True):
""" """
Search rows for metadata. Search rows for metadata.
@ -568,7 +586,7 @@ class Playlist(QTableWidget):
if row in notes_rows: if row in notes_rows:
continue continue
if self.item(row, self.COL_INDEX): if self.item(row, self.COL_INDEX):
self.meta_set_next(row) self.cue_next_track(row)
break break
# Tell database to record it as played # Tell database to record it as played
@ -579,7 +597,7 @@ class Playlist(QTableWidget):
self.played_tracks.append(self.current_track.id) self.played_tracks.append(self.current_track.id)
# Update display # Update display
self.tracks_changed() self.repaint()
def search_database(self): def search_database(self):
dlg = DbDialog(self) dlg = DbDialog(self)
@ -609,8 +627,7 @@ class Playlist(QTableWidget):
return False return False
if self.item(row, self.COL_INDEX): if self.item(row, self.COL_INDEX):
self.meta_set_next(row) self.cue_next_track(row)
self.tracks_changed()
return True return True
return False return False
@ -626,8 +643,8 @@ class Playlist(QTableWidget):
self.previous_track = self.current_track self.previous_track = self.current_track
self.previous_track_position = 0 self.previous_track_position = 0
self.meta_clear(self.meta_get_current()) self.meta_clear_current()
self.tracks_changed() self.repaint()
def repaint(self, clear_selection=True): def repaint(self, clear_selection=True):
"Set row colours, fonts, etc, and save playlist" "Set row colours, fonts, etc, and save playlist"
@ -850,31 +867,21 @@ class Playlist(QTableWidget):
item = QTableWidgetItem(time_str) item = QTableWidgetItem(time_str)
self.setItem(row, self.COL_START_TIME, item) self.setItem(row, self.COL_START_TIME, item)
def tracks_changed(self): def cue_next_track(self, next_row):
""" """
One or more of current or next track has changed. Set the passed row as the next track to play
The row metadata is definitive because the same track may appear
more than once in the playlist, but only one track may be marked
as current or next.
Update self.current_track and self.next_track.
""" """
# Update instance variables
current_row = self.meta_get_current()
if current_row is not None:
track_id = int(self.item(current_row, self.COL_INDEX).text())
if not self.current_track or self.current_track.id != track_id:
self.current_track = Tracks.get_track(track_id)
else:
self.current_track = None
next_row = self.meta_get_next()
if next_row is not None: if next_row is not None:
self.meta_set_next(next_row)
track_id = int(self.item(next_row, self.COL_INDEX).text()) track_id = int(self.item(next_row, self.COL_INDEX).text())
if not self.next_track or self.next_track.id != track_id: if not self.next_track or self.next_track.id != track_id:
self.next_track = Tracks.get_track(track_id) self.next_track = Tracks.get_track(track_id)
# Check we can read it
if not self.can_read_track(self.next_track):
self.parent().parent().show_warning(
"Can't read next track",
self.next_track.path)
else: else:
self.next_track = None self.next_track = None
@ -937,13 +944,11 @@ class DbDialog(QDialog):
def double_click(self, entry): def double_click(self, entry):
track_id = entry.data(Qt.UserRole) track_id = entry.data(Qt.UserRole)
self.add_track(track_id) self.add_track(track_id)
# Select search text to make it easier for next search
self.select_searchtext()
def add_track(self, track_id): def add_track(self, track_id):
track = Tracks.track_from_id(track_id) track = Tracks.track_from_id(track_id)
# Store in current playlist in database
db_playlist = Playlists.get_playlist_by_id(self.parent().playlist_id)
db_playlist.add_track(track)
# Add to on-screen playlist
self.parent().add_to_playlist(track) self.parent().add_to_playlist(track)
# Select search text to make it easier for next search # Select search text to make it easier for next search
self.select_searchtext() self.select_searchtext()