Only invalidate required roles

This commit is contained in:
Keith Edmunds 2025-03-08 21:36:09 +00:00
parent 963da0b5d0
commit 74402f640f
2 changed files with 99 additions and 37 deletions

View File

@ -2308,7 +2308,10 @@ class Window(QMainWindow):
session.commit() session.commit()
self.preview_manager.set_intro(intro) self.preview_manager.set_intro(intro)
self.current.base_model.refresh_row(session, row_number) self.current.base_model.refresh_row(session, row_number)
self.current.base_model.invalidate_row(row_number) roles = [
Qt.ItemDataRole.DisplayRole,
]
self.current.base_model.invalidate_row(row_number, roles)
def preview_start(self) -> None: def preview_start(self) -> None:
"""Restart preview""" """Restart preview"""

View File

@ -173,11 +173,17 @@ class PlaylistModel(QAbstractTableModel):
# Update local copy # Update local copy
self.refresh_row(session, row_number) self.refresh_row(session, row_number)
# Repaint row # Repaint row
self.invalidate_row(row_number) roles = [
Qt.ItemDataRole.BackgroundRole,
Qt.ItemDataRole.DisplayRole,
Qt.ItemDataRole.FontRole,
Qt.ItemDataRole.ForegroundRole,
]
# only invalidate required roles
self.invalidate_row(row_number, roles)
self.signals.resize_rows_signal.emit(self.playlist_id) self.signals.resize_rows_signal.emit(self.playlist_id)
# @line_profiler.profile
def background_role(self, row: int, column: int, rat: RowAndTrack) -> QBrush: def background_role(self, row: int, column: int, rat: RowAndTrack) -> QBrush:
"""Return background setting""" """Return background setting"""
@ -295,11 +301,16 @@ class PlaylistModel(QAbstractTableModel):
) )
# Update colour and times for current row # Update colour and times for current row
self.invalidate_row(row_number) # only invalidate required roles
roles = [
Qt.ItemDataRole.DisplayRole
]
self.invalidate_row(row_number, roles)
# Update previous row in case we're hiding played rows # Update previous row in case we're hiding played rows
if track_sequence.previous and track_sequence.previous.row_number: if track_sequence.previous and track_sequence.previous.row_number:
self.invalidate_row(track_sequence.previous.row_number) # only invalidate required roles
self.invalidate_row(track_sequence.previous.row_number, roles)
# Update all other track times # Update all other track times
self.update_track_times() self.update_track_times()
@ -320,7 +331,6 @@ class PlaylistModel(QAbstractTableModel):
if next_row is not None: if next_row is not None:
self.set_next_row(next_row) self.set_next_row(next_row)
# @line_profiler.profile
def data( def data(
self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole
) -> QVariant | QFont | QBrush | str: ) -> QVariant | QFont | QBrush | str:
@ -329,7 +339,8 @@ class PlaylistModel(QAbstractTableModel):
if ( if (
not index.isValid() not index.isValid()
or not (0 <= index.row() < len(self.playlist_rows)) or not (0 <= index.row() < len(self.playlist_rows))
or role in [ or role
in [
Qt.ItemDataRole.DecorationRole, Qt.ItemDataRole.DecorationRole,
Qt.ItemDataRole.StatusTipRole, Qt.ItemDataRole.StatusTipRole,
Qt.ItemDataRole.WhatsThisRole, Qt.ItemDataRole.WhatsThisRole,
@ -392,7 +403,6 @@ class PlaylistModel(QAbstractTableModel):
self.reset_track_sequence_row_numbers() self.reset_track_sequence_row_numbers()
self.update_track_times() self.update_track_times()
# @line_profiler.profile
def display_role(self, row: int, column: int, rat: RowAndTrack) -> str: def display_role(self, row: int, column: int, rat: RowAndTrack) -> str:
""" """
Return text for display Return text for display
@ -468,7 +478,6 @@ class PlaylistModel(QAbstractTableModel):
super().endResetModel() super().endResetModel()
self.reset_track_sequence_row_numbers() self.reset_track_sequence_row_numbers()
# @line_profiler.profile
def edit_role(self, row: int, column: int, rat: RowAndTrack) -> str: def edit_role(self, row: int, column: int, rat: RowAndTrack) -> str:
""" """
Return text for editing Return text for editing
@ -490,17 +499,17 @@ class PlaylistModel(QAbstractTableModel):
return "" return ""
# @line_profiler.profile
def foreground_role(self, row: int, column: int, rat: RowAndTrack) -> QBrush: def foreground_role(self, row: int, column: int, rat: RowAndTrack) -> QBrush:
"""Return header foreground colour or QBrush() if none""" """Return header foreground colour or QBrush() if none"""
if self.is_header_row(row): if self.is_header_row(row):
with db.Session() as session: if rat.row_fg is None:
note_foreground = NoteColours.get_colour( with db.Session() as session:
session, rat.note, foreground=True rat.row_fg = NoteColours.get_colour(
) session, rat.note, foreground=True
if note_foreground: )
return QBrush(QColor(note_foreground)) if rat.row_fg:
return QBrush(QColor(rat.row_fg))
return QBrush() return QBrush()
@ -527,7 +536,6 @@ class PlaylistModel(QAbstractTableModel):
return default return default
# @line_profiler.profile
def font_role(self, row: int, column: int, rat: RowAndTrack) -> QFont: def font_role(self, row: int, column: int, rat: RowAndTrack) -> QFont:
""" """
Return font Return font
@ -704,7 +712,11 @@ class PlaylistModel(QAbstractTableModel):
self.played_tracks_hidden = hide self.played_tracks_hidden = hide
for row_number in range(len(self.playlist_rows)): for row_number in range(len(self.playlist_rows)):
if self.is_played_row(row_number): if self.is_played_row(row_number):
self.invalidate_row(row_number) # only invalidate required roles
roles = [
Qt.ItemDataRole.DisplayRole,
]
self.invalidate_row(row_number, roles)
def insert_row( def insert_row(
self, self,
@ -736,11 +748,16 @@ class PlaylistModel(QAbstractTableModel):
self.signals.resize_rows_signal.emit(self.playlist_id) self.signals.resize_rows_signal.emit(self.playlist_id)
self.reset_track_sequence_row_numbers() self.reset_track_sequence_row_numbers()
self.invalidate_rows(list(range(new_row_number, len(self.playlist_rows)))) # only invalidate required roles
roles = [
Qt.ItemDataRole.BackgroundRole,
Qt.ItemDataRole.DisplayRole,
Qt.ItemDataRole.FontRole,
Qt.ItemDataRole.ForegroundRole,
]
self.invalidate_rows(list(range(new_row_number, len(self.playlist_rows))), roles)
# Keep this decorator for now def invalidate_row(self, modified_row: int, roles: list[Qt.ItemDataRole]) -> None:
# @line_profiler.profile
def invalidate_row(self, modified_row: int) -> None:
""" """
Signal to view to refresh invalidated row Signal to view to refresh invalidated row
""" """
@ -750,11 +767,10 @@ class PlaylistModel(QAbstractTableModel):
self.dataChanged.emit( self.dataChanged.emit(
self.index(modified_row, 0), self.index(modified_row, 0),
self.index(modified_row, self.columnCount() - 1), self.index(modified_row, self.columnCount() - 1),
roles
) )
# Keep this decorator for now def invalidate_rows(self, modified_rows: list[int], roles: list[Qt.ItemDataRole]) -> None:
# @line_profiler.profile
def invalidate_rows(self, modified_rows: list[int]) -> None:
""" """
Signal to view to refresh invlidated rows Signal to view to refresh invlidated rows
""" """
@ -762,7 +778,8 @@ class PlaylistModel(QAbstractTableModel):
log.debug(f"issue285: {self}: invalidate_rows({modified_rows=})") log.debug(f"issue285: {self}: invalidate_rows({modified_rows=})")
for modified_row in modified_rows: for modified_row in modified_rows:
self.invalidate_row(modified_row) # only invalidate required roles
self.invalidate_row(modified_row, roles)
def is_header_row(self, row_number: int) -> bool: def is_header_row(self, row_number: int) -> bool:
""" """
@ -837,7 +854,11 @@ class PlaylistModel(QAbstractTableModel):
self.refresh_row(session, row_number) self.refresh_row(session, row_number)
self.update_track_times() self.update_track_times()
self.invalidate_rows(row_numbers) # only invalidate required roles
roles = [
Qt.ItemDataRole.FontRole,
]
self.invalidate_rows(row_numbers, roles)
def move_rows(self, from_rows: list[int], to_row_number: int) -> None: def move_rows(self, from_rows: list[int], to_row_number: int) -> None:
""" """
@ -902,7 +923,11 @@ class PlaylistModel(QAbstractTableModel):
# Update display # Update display
self.reset_track_sequence_row_numbers() self.reset_track_sequence_row_numbers()
self.update_track_times() self.update_track_times()
self.invalidate_rows(list(row_map.keys())) # only invalidate required roles
roles = [
Qt.ItemDataRole.DisplayRole,
]
self.invalidate_rows(list(row_map.keys()), roles)
def move_rows_between_playlists( def move_rows_between_playlists(
self, self,
@ -1079,7 +1104,11 @@ class PlaylistModel(QAbstractTableModel):
return return
# Update display # Update display
self.invalidate_row(track_sequence.previous.row_number) # only invalidate required roles
roles = [
Qt.ItemDataRole.BackgroundRole,
]
self.invalidate_row(track_sequence.previous.row_number, roles)
def refresh_data(self, session: Session) -> None: def refresh_data(self, session: Session) -> None:
""" """
@ -1132,7 +1161,11 @@ class PlaylistModel(QAbstractTableModel):
playlist_row.track_id = None playlist_row.track_id = None
session.commit() session.commit()
self.refresh_row(session, row_number) self.refresh_row(session, row_number)
self.invalidate_row(row_number) # only invalidate required roles
roles = [
Qt.ItemDataRole.DisplayRole,
]
self.invalidate_row(row_number, roles)
def rescan_track(self, row_number: int) -> None: def rescan_track(self, row_number: int) -> None:
""" """
@ -1146,7 +1179,12 @@ class PlaylistModel(QAbstractTableModel):
set_track_metadata(track) set_track_metadata(track)
self.refresh_row(session, row_number) self.refresh_row(session, row_number)
self.update_track_times() self.update_track_times()
self.invalidate_row(row_number) roles = [
Qt.ItemDataRole.BackgroundRole,
Qt.ItemDataRole.DisplayRole,
]
# only invalidate required roles
self.invalidate_row(row_number, roles)
self.signals.resize_rows_signal.emit(self.playlist_id) self.signals.resize_rows_signal.emit(self.playlist_id)
session.commit() session.commit()
@ -1206,7 +1244,13 @@ class PlaylistModel(QAbstractTableModel):
# self.playlist_rows directly. # self.playlist_rows directly.
self.playlist_rows[row_number].note = "" self.playlist_rows[row_number].note = ""
session.commit() session.commit()
self.invalidate_rows(row_numbers) # only invalidate required roles
roles = [
Qt.ItemDataRole.BackgroundRole,
Qt.ItemDataRole.DisplayRole,
Qt.ItemDataRole.ForegroundRole,
]
self.invalidate_rows(row_numbers, roles)
def _reversed_contiguous_row_groups( def _reversed_contiguous_row_groups(
self, row_numbers: list[int] self, row_numbers: list[int]
@ -1415,9 +1459,14 @@ class PlaylistModel(QAbstractTableModel):
self.signals.search_songfacts_signal.emit( self.signals.search_songfacts_signal.emit(
self.playlist_rows[row_number].title self.playlist_rows[row_number].title
) )
roles = [
Qt.ItemDataRole.BackgroundRole,
]
if old_next_row is not None: if old_next_row is not None:
self.invalidate_row(old_next_row) # only invalidate required roles
self.invalidate_row(row_number) self.invalidate_row(old_next_row, roles)
# only invalidate required roles
self.invalidate_row(row_number, roles)
self.signals.next_track_changed_signal.emit() self.signals.next_track_changed_signal.emit()
self.update_track_times() self.update_track_times()
@ -1567,7 +1616,6 @@ class PlaylistModel(QAbstractTableModel):
def supportedDropActions(self) -> Qt.DropAction: def supportedDropActions(self) -> Qt.DropAction:
return Qt.DropAction.MoveAction | Qt.DropAction.CopyAction return Qt.DropAction.MoveAction | Qt.DropAction.CopyAction
# @line_profiler.profile
def tooltip_role(self, row: int, column: int, rat: RowAndTrack) -> str: def tooltip_role(self, row: int, column: int, rat: RowAndTrack) -> str:
""" """
Return tooltip. Currently only used for last_played column. Return tooltip. Currently only used for last_played column.
@ -1600,7 +1648,14 @@ class PlaylistModel(QAbstractTableModel):
with db.Session() as session: with db.Session() as session:
for row in track_rows: for row in track_rows:
self.refresh_row(session, row) self.refresh_row(session, row)
self.invalidate_rows(track_rows) # only invalidate required roles
roles = [
Qt.ItemDataRole.BackgroundRole,
Qt.ItemDataRole.DisplayRole,
Qt.ItemDataRole.FontRole,
Qt.ItemDataRole.ForegroundRole,
]
self.invalidate_rows(track_rows, roles)
else: else:
self.insert_row(proposed_row_number=row_number, track_id=track_id) self.insert_row(proposed_row_number=row_number, track_id=track_id)
@ -1749,9 +1804,13 @@ class PlaylistProxyModel(QSortFilterProxyModel):
# milliseconds so that it hides then. We add # milliseconds so that it hides then. We add
# 100mS on so that the if clause above is # 100mS on so that the if clause above is
# true next time through. # true next time through.
# only invalidate required roles
roles = [
Qt.ItemDataRole.DisplayRole,
]
QTimer.singleShot( QTimer.singleShot(
Config.HIDE_AFTER_PLAYING_OFFSET + 100, Config.HIDE_AFTER_PLAYING_OFFSET + 100,
lambda: self.sourceModel().invalidate_row(source_row), lambda: self.sourceModel().invalidate_row(source_row, roles),
) )
return True return True
# Next track not playing yet so don't hide previous # Next track not playing yet so don't hide previous