Clean up header and note updates
• rationalise number of functions • make colour handling cleaner • optimise when playlist is saved
This commit is contained in:
parent
39ec7f470b
commit
80e698680b
@ -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):
|
||||
|
||||
@ -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.
|
||||
|
||||
175
app/playlists.py
175
app/playlists.py
@ -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 """
|
||||
|
||||
Loading…
Reference in New Issue
Block a user