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