Clean up header and note updates

• rationalise number of functions
• make colour handling cleaner
• optimise when playlist is saved
This commit is contained in:
Keith Edmunds 2023-03-12 09:53:11 +00:00
parent 39ec7f470b
commit 80e698680b
3 changed files with 86 additions and 101 deletions

View File

@ -98,13 +98,13 @@ class NoteColours(Base):
)
@staticmethod
def get_colour(session: scoped_session, text: str) -> str:
def get_colour(session: scoped_session, text: str) -> Optional[str]:
"""
Parse text and return colour string if matched, else empty string
"""
if not text:
return ""
return None
for rec in session.execute(
select(NoteColours)
@ -126,7 +126,7 @@ class NoteColours(Base):
if rec.substring.lower() in text.lower():
return rec.colour
return ""
return None
class Playdates(Base):

View File

@ -1518,9 +1518,9 @@ class Window(QMainWindow, Ui_MainWindow):
# May also be called when last tab is closed
pass
def this_is_the_next_playlist_row(self, session: scoped_session,
plr: PlaylistRows,
next_track_playlist_tab: PlaylistTab) -> None:
def this_is_the_next_playlist_row(
self, session: scoped_session, plr: PlaylistRows,
next_track_playlist_tab: PlaylistTab) -> None:
"""
This is notification from a playlist tab that it holds the next
playlist row to be played.

View File

@ -198,7 +198,6 @@ class PlaylistTab(QTableWidget):
# Connect signals
self.horizontalHeader().sectionResized.connect(self._column_resize)
self.signals.save_playlist_signal.connect(self._deferred_save)
self.signals.update_row_note_signal.connect(self._update_row_note)
# Load playlist rows
self.populate_display(session, self.playlist_id)
@ -332,10 +331,11 @@ class PlaylistTab(QTableWidget):
if self.edit_cell_type == ROW_NOTES:
plr_item.note = new_text
session.flush()
self.signals.update_row_note_signal.emit(row)
if track_id:
self._set_row_note_text(session, row, new_text)
else:
self._set_row_header_text(session, row, new_text)
else:
track = None
if track_id:
track = session.get(Tracks, track_id)
if track:
@ -517,9 +517,7 @@ class PlaylistTab(QTableWidget):
row_number = self.get_new_row_number()
plr = PlaylistRows(session, self.playlist_id, None, row_number, note)
self.insert_row(session, plr)
self._set_row_note_colour(session, row_number, note,
section_header=True)
self.save_playlist(session)
self._set_row_header_text(session, row_number, note)
def insert_row(self, session: scoped_session, plr: PlaylistRows,
update_track_times: bool = True, played=False) -> None:
@ -539,7 +537,7 @@ class PlaylistTab(QTableWidget):
_ = self._set_row_userdata(row, self.PLAYED, True)
if plr.note is None:
plr.note = ""
self._set_row_note_colour(session, row, plr.note)
self._set_row_note_text(session, row, plr.note)
else:
# This is a section header so it must have note text
if plr.note is None:
@ -548,13 +546,9 @@ class PlaylistTab(QTableWidget):
)
return
# In order to colour the row, we need items in every column
for i in range(1, len(columns)):
self._set_item_text(row, i, None)
# Use one QTableWidgetItem to span all columns from column 1
self._set_row_header_text(session, row, plr.note)
self.setSpan(row, HEADER_NOTES_COLUMN, 1, len(columns) - 1)
_ = self._set_row_note_colour(session, row, plr.note,
section_header=True)
# Save (or clear) track_id
_ = self._set_row_track_id(row, 0)
@ -562,8 +556,12 @@ class PlaylistTab(QTableWidget):
# Set bold as needed
self._set_row_bold(row, bold)
self.save_playlist(session)
if update_track_times:
self._update_start_end_times()
# Queue up time calculations to take place after UI has
# updated
QTimer.singleShot(0, self._update_start_end_times)
def insert_track(self, session: scoped_session, track: Tracks,
note: str = "", repaint: bool = True) -> None:
@ -603,7 +601,6 @@ class PlaylistTab(QTableWidget):
plr = PlaylistRows(session, self.playlist_id, track.id,
row_number, note)
self.insert_row(session, plr)
self.save_playlist(session)
def play_ended(self) -> None:
"""
@ -889,7 +886,7 @@ class PlaylistTab(QTableWidget):
# Update attributes of row
self._set_row_bold(row)
self._set_row_colour_default(plr.row_number)
_ = self._set_row_note_colour(session, row, plr.note)
self._set_row_header_text(session, row, plr.note)
self._update_row_track_info(session, row, track)
self._update_start_end_times()
self.clear_selection()
@ -1504,10 +1501,7 @@ class PlaylistTab(QTableWidget):
# Span the rows
self.setSpan(row, HEADER_NOTES_COLUMN, 1, len(columns) - 1)
# Set note text in correct column for section head
_ = self._set_item_text(row, HEADER_NOTES_COLUMN, plr.note)
_ = self._set_row_note_colour(session, row, plr.note,
section_header=True)
self._set_row_header_text(session, row, plr.note)
self.clear_selection()
# Set track start/end times after track list is populated
@ -1532,7 +1526,7 @@ class PlaylistTab(QTableWidget):
note_text = ""
else:
note_text += f"{track_id=} not found"
self._set_row_note_colour(session, row, note_text)
self._set_row_header_text(session, row, note_text)
log.error(
f"playlists._rescan({track_id=}): "
"Track not found"
@ -1667,15 +1661,15 @@ class PlaylistTab(QTableWidget):
self.musicmuster.lblSumPlaytime.setText("")
def _set_cell_colour(self, row: int, column: int,
colour: Optional[QColor] = None) -> None:
colour: Optional[str] = None) -> None:
"""
Set or reset a cell background colour
"""
if colour:
brush = QBrush(colour)
else:
if colour is None:
brush = QBrush()
else:
brush = QBrush(QColor(colour))
item = self.item(row, column)
if item:
@ -1829,15 +1823,15 @@ class PlaylistTab(QTableWidget):
item.setFont(boldfont)
def _set_row_colour(self, row: int,
colour: Optional[QColor] = None) -> None:
colour: Optional[str] = None) -> None:
"""
Set or reset row background colour
"""
if colour:
brush = QBrush(colour)
else:
if colour is None:
brush = QBrush()
else:
brush = QBrush(QColor(colour))
for column in range(1, self.columnCount()):
if column in [START_GAP, BITRATE]:
@ -1851,7 +1845,7 @@ class PlaylistTab(QTableWidget):
Set current track row colour
"""
self._set_row_colour(row, QColor(Config.COLOUR_CURRENT_PLAYLIST))
self._set_row_colour(row, Config.COLOUR_CURRENT_PLAYLIST)
def _set_row_colour_default(self, row: int) -> None:
"""
@ -1865,14 +1859,14 @@ class PlaylistTab(QTableWidget):
Set next track row colour
"""
self._set_row_colour(row, QColor(Config.COLOUR_NEXT_PLAYLIST))
self._set_row_colour(row, Config.COLOUR_NEXT_PLAYLIST)
def _set_row_colour_unreadable(self, row: int) -> None:
"""
Set unreadable row colour
"""
self._set_row_colour(row, QColor(Config.COLOUR_UNREADABLE))
self._set_row_colour(row, Config.COLOUR_UNREADABLE)
def _set_row_duration(self, row: int,
ms: Optional[int]) -> QTableWidgetItem:
@ -1897,6 +1891,32 @@ class PlaylistTab(QTableWidget):
return self._set_item_text(row, END_TIME, time_str)
def _set_row_header_text(self, session: scoped_session,
row_number: int, text: str) -> None:
"""
Set header text and row colour
"""
# Sanity check: this should be a header row and thus not have a
# track associate
if self._get_row_track_id(row_number):
send_mail(Config.ERRORS_TO,
Config.ERRORS_FROM,
"playists:_set_row_header_text() called on track row",
stackprinter.format()
)
return
# Set text
_ = self._set_item_text(row_number, HEADER_NOTES_COLUMN, text)
# Set colour
note_colour = NoteColours.get_colour(session, text)
if not note_colour:
note_colour = Config.COLOUR_NOTES_PLAYLIST
self._set_row_colour(row_number, note_colour)
def _set_row_last_played(self, row: int, last_played: Optional[datetime]) \
-> QTableWidgetItem:
"""Set row last played time"""
@ -1910,34 +1930,28 @@ class PlaylistTab(QTableWidget):
self._set_row_bold(row, False)
def _set_row_note_colour(self, session: scoped_session, row: int,
note_text: Optional[str],
section_header: bool = False) -> QTableWidgetItem:
"""Set row note and colour"""
def _set_row_note_text(self, session: scoped_session,
row_number: int, text: str) -> None:
"""
Set row note text and note colour
"""
if section_header:
column = HEADER_NOTES_COLUMN
else:
column = ROW_NOTES
# Sanity check: this should be a track row and thus have a
# track associated
if not self._get_row_track_id(row_number):
send_mail(Config.ERRORS_TO,
Config.ERRORS_FROM,
"playists:_set_row_note_text() called on header row",
stackprinter.format()
)
return
if not note_text:
note_text = ""
# Set text
_ = self._set_item_text(row_number, ROW_NOTES, text)
notes_item = self._set_item_text(row, column, note_text)
note_colour = NoteColours.get_colour(session, note_text)
if section_header and not note_colour:
note_colour = Config.COLOUR_NOTES_PLAYLIST
if note_colour:
new_colour = QColor(note_colour)
else:
new_colour = None
if section_header:
self._set_row_colour(row, new_colour)
else:
self._set_cell_colour(row, column, new_colour)
return notes_item
# Set colour
note_colour = NoteColours.get_colour(session, text)
self._set_cell_colour(row_number, ROW_NOTES, note_colour)
def _set_row_plr_id(self, row: int, plr_id: int) -> QTableWidgetItem:
"""
@ -2055,19 +2069,6 @@ class PlaylistTab(QTableWidget):
return total_time
def _update_note_text(self, playlist_row: PlaylistRows,
new_text: str) -> None:
"""Update note text"""
# Column to update is either HEADER_NOTES_COLUMN for a section
# header or the appropriate row_notes column for a track row
if playlist_row.track_id:
column = ROW_NOTES
else:
column = HEADER_NOTES_COLUMN
_ = self._set_item_text(playlist_row.row_number, column, new_text)
def _update_row_track_info(self, session: scoped_session, row: int,
track: Tracks) -> None:
"""
@ -2089,26 +2090,6 @@ class PlaylistTab(QTableWidget):
if not file_is_readable(track.path):
self._set_row_colour_unreadable(row)
def _update_row_note(self, row_number: int) -> None:
"""
Called by signal when row note is updated
"""
# Set/clear row start time accordingly
note_text = self._get_row_note(row_number)
start_time = self._get_note_text_time(note_text)
if start_time:
self._set_row_start_time(row_number, start_time)
else:
self._set_row_start_time(row_number, None)
is_section_header = not bool(self._get_row_track_id(row_number))
with Session() as session:
self._set_row_note_colour(session, row_number, note_text,
section_header=is_section_header)
self._update_start_end_times()
def _update_section_headers(self, session: scoped_session) -> None:
"""
Update section headers with run time of section
@ -2133,7 +2114,8 @@ class PlaylistTab(QTableWidget):
total_time = self._track_time_between_rows(
session, from_plr, to_plr)
time_str = self._get_section_timing_string(total_time)
self._update_note_text(from_plr, from_plr.note + time_str)
self._set_row_header_text(session, from_plr.row_number,
from_plr.note + time_str)
# Update section end
if to_plr.note.strip() == "-":
@ -2142,11 +2124,13 @@ class PlaylistTab(QTableWidget):
section_header_cleanup_re, '', from_plr.note,
).strip() + "]"
)
self._update_note_text(plr, new_text)
self._set_row_header_text(session, plr.row_number,
new_text)
except IndexError:
# This ending row may have a time left from before a
# starting row above was deleted, so replace content
self._update_note_text(plr, plr.note)
self._set_row_header_text(session, plr.row_number,
plr.note)
continue
# If we still have plrs in section_start_rows, there isn't an end
@ -2159,7 +2143,8 @@ class PlaylistTab(QTableWidget):
from_plr, to_plr)
time_str = self._get_section_timing_string(total_time,
no_end=True)
self._update_note_text(from_plr, from_plr.note + time_str)
self._set_row_header_text(session, from_plr.row_number,
from_plr.note + time_str)
def _update_start_end_times(self) -> None:
""" Update track start and end times """