Change row to row_number

This commit is contained in:
Keith Edmunds 2023-03-12 18:43:23 +00:00
parent c6840d2356
commit 380806d27a

View File

@ -1291,7 +1291,10 @@ class PlaylistTab(QTableWidget):
return ' [' + duration + caveat + ']'
def _get_selected_row(self) -> Optional[int]:
"""Return row_number number of first selected row, or None if none selected"""
"""
Return row_number number of first selected row,
or None if none selected
"""
if not self.selectionModel().hasSelection():
return None
@ -1304,7 +1307,8 @@ class PlaylistTab(QTableWidget):
# Use a set to deduplicate result (a selected row will have all
# items in that row selected)
return sorted(
[row_number for row_number in set([a.row() for a in self.selectedItems()])]
[row_number for row_number in
set([a.row() for a in self.selectedItems()])]
)
def _info_row(self, track_id: int) -> None:
@ -1387,6 +1391,7 @@ class PlaylistTab(QTableWidget):
plr.row_number = new_row_number
self.insert_row(session, plr)
self.save_playlist(session)
self.hide_or_show_played_tracks()
# Queue up time calculations to take place after UI has
# updated
QTimer.singleShot(0, self._update_start_end_times)
@ -1432,7 +1437,7 @@ class PlaylistTab(QTableWidget):
return None
def _remove_track(self, row: int) -> None:
def _remove_track(self, row_number: int) -> None:
"""Remove track from row, making it a section header"""
# Get confirmation
@ -1442,7 +1447,7 @@ class PlaylistTab(QTableWidget):
# Update playlist_rows record
with Session() as session:
plr = self._get_row_plr(session, row)
plr = self._get_row_plr(session, row_number)
if not plr:
return
@ -1454,47 +1459,47 @@ class PlaylistTab(QTableWidget):
# Clear track text items
for i in range(2, len(columns)):
_ = self._set_item_text(row, i, "")
_ = self._set_item_text(row_number, i, "")
# Remove row duration
self._set_row_duration(row, 0)
self._set_row_duration(row_number, 0)
# Remove row start gap
self._set_row_start_gap(row, None)
self._set_row_start_gap(row_number, None)
# Remote track_id from row
_ = self._set_row_userdata(row, self.ROW_TRACK_ID, 0)
_ = self._set_row_userdata(row_number, self.ROW_TRACK_ID, 0)
# Span the rows
self.setSpan(row, HEADER_NOTES_COLUMN, 1, len(columns) - 1)
self.setSpan(row_number, HEADER_NOTES_COLUMN, 1, len(columns) - 1)
# Set note text in correct column for section head
self._set_row_header_text(session, row, plr.note)
self._set_row_header_text(session, row_number, plr.note)
self.clear_selection()
# Set track start/end times after track list is populated
QTimer.singleShot(0, self._update_start_end_times)
def _rescan(self, row: int, track_id: int) -> None:
def _rescan(self, row_number: int, track_id: int) -> None:
"""Rescan track"""
with Session() as session:
track = session.get(Tracks, track_id)
if track:
if file_is_unreadable(track.path):
self._set_row_colour_unreadable(row)
self._set_row_colour_unreadable(row_number)
else:
self._set_row_colour_default(row)
self._set_row_colour_default(row_number)
set_track_metadata(session, track)
self._update_row_track_info(session, row, track)
self._update_row_track_info(session, row_number, track)
else:
_ = self._set_row_track_id(row, 0)
note_text = self._get_row_note(row)
_ = self._set_row_track_id(row_number, 0)
note_text = self._get_row_note(row_number)
if note_text is None:
note_text = ""
else:
note_text += f"{track_id=} not found"
self._set_row_header_text(session, row, note_text)
self._set_row_header_text(session, row_number, note_text)
log.error(
f"playlists._rescan({track_id=}): "
"Track not found"
)
self._set_row_colour_unreadable(row)
self._set_row_colour_unreadable(row_number)
self._update_start_end_times()
self.clear_selection()
@ -1504,25 +1509,24 @@ class PlaylistTab(QTableWidget):
subprocess.call(args)
def _scroll_to_top(self, row: int) -> None:
def _scroll_to_top(self, row_number: int) -> None:
"""
Scroll to put passed row Config.SCROLL_TOP_MARGIN from the
Scroll to put passed row_number Config.SCROLL_TOP_MARGIN from the
top.
"""
if row is None:
if row_number is None:
return
padding_required = Config.SCROLL_TOP_MARGIN
top_row = row
top_row = row_number
if row > Config.SCROLL_TOP_MARGIN:
# We can't scroll to a hidden row. Calculate target_row as the
# one that is ideal to be at the top. Then count upwards from
# passed row until we either reach the target, pass it or reach
# row 0.
# target_row = max(0, row - Config.SCROLL_TOP_MARGIN + 1)
for i in range(row - 1, -1, -1):
if row_number > Config.SCROLL_TOP_MARGIN:
# We can't scroll to a hidden row. Calculate target_row as
# the one that is ideal to be at the top. Then count upwards
# from passed row_number until we either reach the target,
# pass it or reach row_number 0.
for i in range(row_number - 1, -1, -1):
if self.isRowHidden(i):
continue
if padding_required == 0:
@ -1558,39 +1562,39 @@ class PlaylistTab(QTableWidget):
wrapped = False
match_row = None
row = starting_row
row_number = starting_row
needle = self.search_text.lower()
while True:
# Check for match in title, artist or notes
title = self._get_row_title(row)
title = self._get_row_title(row_number)
if title and needle in title.lower():
match_row = row
match_row = row_number
break
artist = self._get_row_artist(row)
artist = self._get_row_artist(row_number)
if artist and needle in artist.lower():
match_row = row
match_row = row_number
break
note = self._get_row_note(row)
note = self._get_row_note(row_number)
if note and needle in note.lower():
match_row = row
match_row = row_number
break
if next:
row += 1
if wrapped and row >= starting_row:
row_number += 1
if wrapped and row_number >= starting_row:
break
if row >= self.rowCount():
row = 0
if row_number >= self.rowCount():
row_number = 0
wrapped = True
else:
row -= 1
if wrapped and row <= starting_row:
row_number -= 1
if wrapped and row_number <= starting_row:
break
if row < 0:
row = self.rowCount() - 1
if row_number < 0:
row_number = self.rowCount() - 1
wrapped = True
if match_row is not None:
self.selectRow(row)
self.selectRow(row_number)
def _select_event(self) -> None:
"""
@ -1614,8 +1618,8 @@ class PlaylistTab(QTableWidget):
QTimer.singleShot(0, lambda: self._wikipedia(selected_rows[0]))
ms = 0
for row in selected_rows:
ms += self._get_row_duration(row)
for row_number in selected_rows:
ms += self._get_row_duration(row_number)
if ms > 0:
self.musicmuster.lblSumPlaytime.setText(
@ -1623,7 +1627,7 @@ class PlaylistTab(QTableWidget):
else:
self.musicmuster.lblSumPlaytime.setText("")
def _set_cell_colour(self, row: int, column: int,
def _set_cell_colour(self, row_number: int, column: int,
colour: Optional[str] = None) -> None:
"""
Set or reset a cell background colour
@ -1634,7 +1638,7 @@ class PlaylistTab(QTableWidget):
else:
brush = QBrush(QColor(colour))
item = self.item(row, column)
item = self.item(row_number, column)
if item:
item.setBackground(brush)
@ -1654,7 +1658,7 @@ class PlaylistTab(QTableWidget):
else:
self.setColumnWidth(idx, Config.DEFAULT_COLUMN_WIDTH)
def _set_item_text(self, row: int, column: int,
def _set_item_text(self, row_number: int, column: int,
text: Optional[str]) -> QTableWidgetItem:
"""
Set text for item if it exists, else create it, and return item
@ -1663,10 +1667,10 @@ class PlaylistTab(QTableWidget):
if not text:
text = ""
item = self.item(row, column)
item = self.item(row_number, column)
if not item:
item = QTableWidgetItem(text)
self.setItem(row, column, item)
self.setItem(row_number, column, item)
else:
item.setText(text)
@ -1720,20 +1724,21 @@ class PlaylistTab(QTableWidget):
self.clear_selection()
self._update_start_end_times()
def _set_played_row(self, session: scoped_session, row: int) -> None:
def _set_played_row(self, session: scoped_session,
row_number: int) -> None:
"""Mark this row as played"""
_ = self._set_row_userdata(row, self.PLAYED, True)
self._set_row_bold(row, False)
_ = self._set_row_userdata(row_number, self.PLAYED, True)
self._set_row_bold(row_number, False)
plr = self._get_row_plr(session, row)
plr = self._get_row_plr(session, row_number)
if not plr:
return
plr.played = True
session.flush()
def _set_row_artist(self, row: int,
def _set_row_artist(self, row_number: int,
artist: Optional[str]) -> QTableWidgetItem:
"""
Set row artist.
@ -1744,9 +1749,9 @@ class PlaylistTab(QTableWidget):
if not artist:
artist = ""
return self._set_item_text(row, ARTIST, artist)
return self._set_item_text(row_number, ARTIST, artist)
def _set_row_bitrate(self, row: int,
def _set_row_bitrate(self, row_number: int,
bitrate: Optional[int]) -> QTableWidgetItem:
"""Set bitrate of this row."""
@ -1756,7 +1761,7 @@ class PlaylistTab(QTableWidget):
bitrate = Config.BITRATE_LOW_THRESHOLD - 1
else:
bitrate_str = str(bitrate)
bitrate_item = self._set_item_text(row, BITRATE, bitrate_str)
bitrate_item = self._set_item_text(row_number, BITRATE, bitrate_str)
if bitrate < Config.BITRATE_LOW_THRESHOLD:
cell_colour = Config.COLOUR_BITRATE_LOW
@ -1769,7 +1774,7 @@ class PlaylistTab(QTableWidget):
return bitrate_item
def _set_row_bold(self, row: int, bold: bool = True) -> None:
def _set_row_bold(self, row_number: int, bold: bool = True) -> None:
"""
Make row bold (bold=True) or not bold.
@ -1781,11 +1786,11 @@ class PlaylistTab(QTableWidget):
for column in range(self.columnCount()):
if column == ROW_NOTES:
continue
item = self.item(row, column)
item = self.item(row_number, column)
if item:
item.setFont(boldfont)
def _set_row_colour(self, row: int,
def _set_row_colour(self, row_number: int,
colour: Optional[str] = None) -> None:
"""
Set or reset row background colour
@ -1799,48 +1804,49 @@ class PlaylistTab(QTableWidget):
for column in range(1, self.columnCount()):
if column in [START_GAP, BITRATE]:
continue
item = self.item(row, column)
item = self.item(row_number, column)
if item:
item.setBackground(brush)
def _set_row_colour_current(self, row: int) -> None:
def _set_row_colour_current(self, row_number: int) -> None:
"""
Set current track row colour
"""
self._set_row_colour(row, Config.COLOUR_CURRENT_PLAYLIST)
self._set_row_colour(row_number, Config.COLOUR_CURRENT_PLAYLIST)
def _set_row_colour_default(self, row: int) -> None:
def _set_row_colour_default(self, row_number: int) -> None:
"""
Set default row colour
"""
self._set_row_colour(row, None)
self._set_row_colour(row_number, None)
def _set_row_colour_next(self, row: int) -> None:
def _set_row_colour_next(self, row_number: int) -> None:
"""
Set next track row colour
"""
self._set_row_colour(row, Config.COLOUR_NEXT_PLAYLIST)
self._set_row_colour(row_number, Config.COLOUR_NEXT_PLAYLIST)
def _set_row_colour_unreadable(self, row: int) -> None:
def _set_row_colour_unreadable(self, row_number: int) -> None:
"""
Set unreadable row colour
"""
self._set_row_colour(row, Config.COLOUR_UNREADABLE)
self._set_row_colour(row_number, Config.COLOUR_UNREADABLE)
def _set_row_duration(self, row: int,
def _set_row_duration(self, row_number: int,
ms: Optional[int]) -> QTableWidgetItem:
"""Set duration of this row. Also set in row metadata"""
duration_item = self._set_item_text(row, DURATION, ms_to_mmss(ms))
self._set_row_userdata(row, self.ROW_DURATION, ms)
duration_item = self._set_item_text(
row_number, DURATION, ms_to_mmss(ms))
self._set_row_userdata(row_number, self.ROW_DURATION, ms)
return duration_item
def _set_row_end_time(self, row: int,
def _set_row_end_time(self, row_number: int,
time: Optional[datetime]) -> QTableWidgetItem:
"""Set row end time"""
@ -1852,7 +1858,7 @@ class PlaylistTab(QTableWidget):
except AttributeError:
time_str = ""
return self._set_item_text(row, END_TIME, time_str)
return self._set_item_text(row_number, END_TIME, time_str)
def _set_row_header_text(self, session: scoped_session,
row_number: int, text: str) -> None:
@ -1880,18 +1886,14 @@ class PlaylistTab(QTableWidget):
self._set_row_colour(row_number, note_colour)
def _set_row_last_played(self, row: int, last_played: Optional[datetime]) \
-> QTableWidgetItem:
def _set_row_last_played_time(
self, row_number: int,
last_played: Optional[datetime]) -> QTableWidgetItem:
"""Set row last played time"""
last_played_str = get_relative_date(last_played)
return self._set_item_text(row, LASTPLAYED, last_played_str)
def _set_row_not_bold(self, row: int) -> None:
"""Set row to not be bold"""
self._set_row_bold(row, False)
return self._set_item_text(row_number, LASTPLAYED, last_played_str)
def _set_row_note_colour(self, session: scoped_session,
row_number: int) -> None:
@ -1936,14 +1938,15 @@ class PlaylistTab(QTableWidget):
# Set colour
self._set_row_note_colour(session, row_number)
def _set_row_plr_id(self, row: int, plr_id: int) -> QTableWidgetItem:
def _set_row_plr_id(self, row_number: int,
plr_id: int) -> QTableWidgetItem:
"""
Set PlaylistRows id
"""
return self._set_row_userdata(row, self.PLAYLISTROW_ID, plr_id)
return self._set_row_userdata(row_number, self.PLAYLISTROW_ID, plr_id)
def _set_row_start_gap(self, row: int,
def _set_row_start_gap(self, row_number: int,
start_gap: Optional[int]) -> QTableWidgetItem:
"""
Set start gap on row, set backgroud colour.
@ -1953,15 +1956,17 @@ class PlaylistTab(QTableWidget):
if not start_gap:
start_gap = 0
start_gap_item = self._set_item_text(row, START_GAP, str(start_gap))
start_gap_item = self._set_item_text(
row_number, START_GAP, str(start_gap))
if start_gap >= 500:
start_gap_item.setBackground(QColor(Config.COLOUR_LONG_START))
brush = QBrush(QColor(Config.COLOUR_LONG_START))
else:
start_gap_item.setBackground(QColor("white"))
brush = QBrush()
start_gap_item.setBackground(brush)
return start_gap_item
def _set_row_start_time(self, row: int,
def _set_row_start_time(self, row_number: int,
time: Optional[datetime]) -> QTableWidgetItem:
"""Set row start time"""
@ -1973,21 +1978,21 @@ class PlaylistTab(QTableWidget):
except AttributeError:
time_str = ""
return self._set_item_text(row, START_TIME, time_str)
return self._set_item_text(row_number, START_TIME, time_str)
def _set_row_times(self, row: int, start: datetime,
def _set_row_times(self, row_number: int, start: datetime,
duration: int) -> Optional[datetime]:
"""
Set row start and end times, return end time
"""
self._set_row_start_time(row, start)
self._set_row_start_time(row_number, start)
end_time = self._calculate_end_time(start, duration)
self._set_row_end_time(row, end_time)
self._set_row_end_time(row_number, end_time)
return end_time
def _set_row_title(self, row: int,
def _set_row_title(self, row_number: int,
title: Optional[str]) -> QTableWidgetItem:
"""
Set row title.
@ -1996,33 +2001,35 @@ class PlaylistTab(QTableWidget):
if not title:
title = ""
return self._set_item_text(row, TITLE, title)
return self._set_item_text(row_number, TITLE, title)
def _set_row_track_id(self, row: int, track_id: int) -> QTableWidgetItem:
def _set_row_track_id(self, row_number: int,
track_id: int) -> QTableWidgetItem:
"""
Set track id
"""
return self._set_row_userdata(row, self.ROW_TRACK_ID, track_id)
return self._set_row_userdata(row_number, self.ROW_TRACK_ID, track_id)
def _set_row_track_path(self, row: int, path: str) -> QTableWidgetItem:
def _set_row_track_path(self, row_number: int,
path: str) -> QTableWidgetItem:
"""
Set track path
"""
return self._set_row_userdata(row, self.TRACK_PATH, path)
return self._set_row_userdata(row_number, self.TRACK_PATH, path)
def _set_row_userdata(self, row: int, role: int,
def _set_row_userdata(self, row_number: int, role: int,
value: Optional[Union[str, int]]) \
-> QTableWidgetItem:
"""
Set passed userdata in USERDATA column
"""
item = self.item(row, USERDATA)
item = self.item(row_number, USERDATA)
if not item:
item = QTableWidgetItem()
self.setItem(row, USERDATA, item)
self.setItem(row_number, USERDATA, item)
item.setData(role, value)
@ -2062,7 +2069,7 @@ class PlaylistTab(QTableWidget):
_ = self._set_row_bitrate(row, track.bitrate)
_ = self._set_row_duration(row, track.duration)
_ = self._set_row_end_time(row, None)
_ = self._set_row_last_played(
_ = self._set_row_last_played_time(
row, Playdates.last_played(session, track.id))
_ = self._set_row_start_gap(row, track.start_gap)
_ = self._set_row_start_time(row, None)
@ -2141,39 +2148,40 @@ class PlaylistTab(QTableWidget):
next_track_row = self._get_next_track_row_number()
played_rows = self._get_played_rows(session)
for row in range(self.rowCount()):
for row_number in range(self.rowCount()):
# Don't change start times for tracks that have been
# played other than current/next row
if row in played_rows and row not in [
if row_number in played_rows and row_number not in [
current_track_row, next_track_row]:
continue
# Get any timing from header row (that's all we need)
if self._get_row_track_id(row) == 0:
if self._get_row_track_id(row_number) == 0:
note_time = self._get_note_text_time(
self._get_row_note(row))
self._get_row_note(row_number))
if note_time:
next_start_time = note_time
continue
# We have a track. Skip if it is unreadable
if file_is_unreadable(self._get_row_path(row)):
if file_is_unreadable(self._get_row_path(row_number)):
continue
# Set next track start from end of current track
if row == next_track_row:
if row_number == next_track_row:
if current_track_end_time:
next_start_time = self._set_row_times(
row, current_track_end_time,
self._get_row_duration(row))
row_number, current_track_end_time,
self._get_row_duration(row_number))
continue
# Else set track times below
if row == current_track_row:
if row_number == current_track_row:
if not current_track_start_time:
continue
self._set_row_start_time(row, current_track_start_time)
self._set_row_end_time(row, current_track_end_time)
self._set_row_start_time(row_number,
current_track_start_time)
self._set_row_end_time(row_number, current_track_end_time)
# Next track may be above us so only reset
# next_start_time if it's not set
if not next_start_time:
@ -2182,19 +2190,20 @@ class PlaylistTab(QTableWidget):
if not next_start_time:
# Clear any existing times
self._set_row_start_time(row, None)
self._set_row_end_time(row, None)
self._set_row_start_time(row_number, None)
self._set_row_end_time(row_number, None)
continue
# If we're between the current and next row, zero out
# times
if (current_track_row and next_track_row and
current_track_row < row < next_track_row):
self._set_row_start_time(row, None)
self._set_row_end_time(row, None)
current_track_row < row_number < next_track_row):
self._set_row_start_time(row_number, None)
self._set_row_end_time(row_number, None)
else:
next_start_time = self._set_row_times(
row, next_start_time, self._get_row_duration(row))
row_number, next_start_time,
self._get_row_duration(row_number))
self._update_section_headers(session)