Remove rows from playlist works and db updates
This commit is contained in:
parent
35b101a538
commit
444c3e4fb4
@ -457,7 +457,7 @@ class PlaylistRows(Base):
|
||||
-> None:
|
||||
"""
|
||||
Delete rows in given playlist that have a higher row number
|
||||
than 'row'
|
||||
than 'maxrow'
|
||||
"""
|
||||
|
||||
# Log the rows to be deleted
|
||||
@ -470,9 +470,7 @@ class PlaylistRows(Base):
|
||||
return
|
||||
|
||||
for row in rows_to_go:
|
||||
log.debug(f"Should delete: {row}")
|
||||
# If needed later:
|
||||
# session.delete(row)
|
||||
session.delete(row)
|
||||
|
||||
@staticmethod
|
||||
def delete_rows(session: Session, ids: List[int]) -> None:
|
||||
@ -617,23 +615,22 @@ class PlaylistRows(Base):
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def indexed_by_row(session: Session, playlist_id: int) -> dict:
|
||||
def indexed_by_id(session: Session, plr_ids: List[int]) -> dict:
|
||||
"""
|
||||
Return a dictionary of playlist_rows indexed by row number for
|
||||
the passed playlist_id.
|
||||
Return a dictionary of playlist_rows indexed by their plr id from
|
||||
the passed plr_id list.
|
||||
"""
|
||||
|
||||
plrs = session.execute(
|
||||
select(PlaylistRows)
|
||||
.where(
|
||||
PlaylistRows.playlist_id == playlist_id,
|
||||
PlaylistRows.id.in_(plr_ids)
|
||||
)
|
||||
.order_by(PlaylistRows.row_number)
|
||||
).scalars().all()
|
||||
|
||||
result = {}
|
||||
for plr in plrs:
|
||||
result[plr.row_number] = plr
|
||||
result[plr.id] = plr
|
||||
|
||||
return result
|
||||
|
||||
|
||||
156
app/playlists.py
156
app/playlists.py
@ -822,22 +822,39 @@ class PlaylistTab(QTableWidget):
|
||||
|
||||
def save_playlist(self, session: Session) -> None:
|
||||
"""
|
||||
All playlist rows have a PlaylistRows id. Check that that id points
|
||||
to this playlist (in case track has been moved from other) and that
|
||||
the row number is correct (in case tracks have been reordered).
|
||||
Get the PlaylistRow objects for each row in the display. Correct
|
||||
the row_number and playlist_id if necessary. Remove any row
|
||||
numbers in the database that are higher than the last row in
|
||||
the display.
|
||||
"""
|
||||
|
||||
plr_dict = PlaylistRows.indexed_by_row(session, self.playlist_id)
|
||||
# Build a dictionary of
|
||||
# {display_row_number: display_row_plr_id}
|
||||
display_plr_ids = {row_number: self._get_playlistrow_id(row_number)
|
||||
for row_number in range(self.rowCount())}
|
||||
|
||||
# Now build a dictionary of
|
||||
# {display_row_number: display_row_plr}
|
||||
plr_dict_by_id = PlaylistRows.indexed_by_id(session,
|
||||
display_plr_ids.values())
|
||||
|
||||
# Finally a dictionary of
|
||||
# {display_row_number: plr}
|
||||
row_plr = {row_number: plr_dict_by_id[display_plr_ids[row_number]]
|
||||
for row_number in range(self.rowCount())}
|
||||
|
||||
# Ensure all row plrs have correct row number and playlist_id
|
||||
for row in range(self.rowCount()):
|
||||
# Set the row number and playlist id (even if correct)
|
||||
plr_dict[row].row_number = row
|
||||
plr_dict[row].playlist_id = self.playlist_id
|
||||
row_plr[row].row_number = row
|
||||
row_plr[row].playlist_id = self.playlist_id
|
||||
|
||||
# Any rows in the database with a row_number higher that the
|
||||
# current value of 'row' should not be there. Commit session
|
||||
# first to ensure any changes made above are committed.
|
||||
session.commit()
|
||||
PlaylistRows.delete_higher_rows(session, self.playlist_id, row)
|
||||
PlaylistRows.delete_higher_rows(session, self.playlist_id,
|
||||
self.rowCount() - 1)
|
||||
session.commit()
|
||||
|
||||
def scroll_current_to_top(self) -> None:
|
||||
"""Scroll currently-playing row to top"""
|
||||
@ -860,65 +877,6 @@ class PlaylistTab(QTableWidget):
|
||||
return
|
||||
self._search(next=True)
|
||||
|
||||
def _search(self, next: bool = True) -> None:
|
||||
"""
|
||||
Select next/previous row containg self.search_string. Start from
|
||||
top selected row if there is one, else from top.
|
||||
|
||||
Wrap at last/first row.
|
||||
"""
|
||||
|
||||
if not self.search_text:
|
||||
return
|
||||
|
||||
selected_row = self._get_selected_row()
|
||||
if next:
|
||||
if selected_row is not None and selected_row < self.rowCount() - 1:
|
||||
starting_row = selected_row + 1
|
||||
else:
|
||||
starting_row = 0
|
||||
else:
|
||||
if selected_row is not None and selected_row > 0:
|
||||
starting_row = selected_row - 1
|
||||
else:
|
||||
starting_row = self.rowCount() - 1
|
||||
|
||||
wrapped = False
|
||||
match_row = None
|
||||
row = starting_row
|
||||
needle = self.search_text.lower()
|
||||
while True:
|
||||
# Check for match in title, artist or notes
|
||||
title = self._get_row_title(row)
|
||||
if title and needle in title.lower():
|
||||
match_row = row
|
||||
break
|
||||
artist = self._get_row_artist(row)
|
||||
if artist and needle in artist.lower():
|
||||
match_row = row
|
||||
break
|
||||
note = self._get_row_note(row)
|
||||
if note and needle in note.lower():
|
||||
match_row = row
|
||||
break
|
||||
if next:
|
||||
row += 1
|
||||
if wrapped and row >= starting_row:
|
||||
break
|
||||
if row >= self.rowCount():
|
||||
row = 0
|
||||
wrapped = True
|
||||
else:
|
||||
row -= 1
|
||||
if wrapped and row <= starting_row:
|
||||
break
|
||||
if row < 0:
|
||||
row = self.rowCount() - 1
|
||||
wrapped = True
|
||||
|
||||
if match_row is not None:
|
||||
self.selectRow(row)
|
||||
|
||||
def search_next(self) -> None:
|
||||
"""
|
||||
Select next row containg self.search_string.
|
||||
@ -1541,11 +1499,6 @@ class PlaylistTab(QTableWidget):
|
||||
|
||||
return self._meta_search(RowMeta.UNREADABLE, one=False)
|
||||
|
||||
# def _header_click(self, index: int) -> None:
|
||||
# """Handle playlist header click"""
|
||||
|
||||
# print(f"_header_click({index=})")
|
||||
|
||||
def _info_row(self, track_id: int) -> None:
|
||||
"""Display popup with info re row"""
|
||||
|
||||
@ -1765,6 +1718,65 @@ class PlaylistTab(QTableWidget):
|
||||
scroll_item = self.item(top_row, 0)
|
||||
self.scrollToItem(scroll_item, QAbstractItemView.PositionAtTop)
|
||||
|
||||
def _search(self, next: bool = True) -> None:
|
||||
"""
|
||||
Select next/previous row containg self.search_string. Start from
|
||||
top selected row if there is one, else from top.
|
||||
|
||||
Wrap at last/first row.
|
||||
"""
|
||||
|
||||
if not self.search_text:
|
||||
return
|
||||
|
||||
selected_row = self._get_selected_row()
|
||||
if next:
|
||||
if selected_row is not None and selected_row < self.rowCount() - 1:
|
||||
starting_row = selected_row + 1
|
||||
else:
|
||||
starting_row = 0
|
||||
else:
|
||||
if selected_row is not None and selected_row > 0:
|
||||
starting_row = selected_row - 1
|
||||
else:
|
||||
starting_row = self.rowCount() - 1
|
||||
|
||||
wrapped = False
|
||||
match_row = None
|
||||
row = starting_row
|
||||
needle = self.search_text.lower()
|
||||
while True:
|
||||
# Check for match in title, artist or notes
|
||||
title = self._get_row_title(row)
|
||||
if title and needle in title.lower():
|
||||
match_row = row
|
||||
break
|
||||
artist = self._get_row_artist(row)
|
||||
if artist and needle in artist.lower():
|
||||
match_row = row
|
||||
break
|
||||
note = self._get_row_note(row)
|
||||
if note and needle in note.lower():
|
||||
match_row = row
|
||||
break
|
||||
if next:
|
||||
row += 1
|
||||
if wrapped and row >= starting_row:
|
||||
break
|
||||
if row >= self.rowCount():
|
||||
row = 0
|
||||
wrapped = True
|
||||
else:
|
||||
row -= 1
|
||||
if wrapped and row <= starting_row:
|
||||
break
|
||||
if row < 0:
|
||||
row = self.rowCount() - 1
|
||||
wrapped = True
|
||||
|
||||
if match_row is not None:
|
||||
self.selectRow(row)
|
||||
|
||||
def _select_event(self) -> None:
|
||||
"""
|
||||
Called when item selection changes.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user