diff --git a/app/musicmuster.py b/app/musicmuster.py index 9271863..b2f7309 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -529,7 +529,9 @@ class Window(QMainWindow, Ui_MainWindow): lambda: self.tabPlaylist.currentWidget().lookup_row_in_wikipedia() ) self.actionSearch.triggered.connect(self.search_playlist) - self.actionSelect_duplicate_rows.triggered.connect(self.select_duplicate_rows) + self.actionSelect_duplicate_rows.triggered.connect( + lambda: self.active_tab().select_duplicate_rows() + ) self.actionSelect_next_track.triggered.connect(self.select_next_row) self.actionSelect_previous_track.triggered.connect(self.select_previous_row) self.actionMoveUnplayed.triggered.connect(self.move_unplayed) @@ -1296,35 +1298,6 @@ class Window(QMainWindow, Ui_MainWindow): self.active_tab().set_search(self.txtSearch.text()) self.enable_play_next_controls() - def select_duplicate_rows(self) -> None: - """ - Select the last of any rows with duplicate tracks in current playlist. - This allows the selection to typically come towards the end of the playlist away - from any show specific sections. - If there a track is selected on three or more rows, only the last one is selected. - """ - - visible_playlist_id = self.active_tab().playlist_id - # Get row number of duplicate rows - sql = text( - f""" - SELECT max(plr_rownum) - FROM playlist_rows - WHERE playlist_id = {visible_playlist_id} - AND track_id != 0 - GROUP BY track_id - HAVING count(id) > 1 - """ - ) - - with Session() as session: - row_numbers = [int(a) for a in session.execute(sql).scalars().all()] - if row_numbers: - self.active_tab().select_rows(row_numbers) - self.statusbar.showMessage( - f"{len(row_numbers)} duplicate rows selected", 10000 - ) - def select_next_row(self) -> None: """Select next or first row in playlist""" diff --git a/app/playlistmodel.py b/app/playlistmodel.py index 8ef1867..04b9608 100644 --- a/app/playlistmodel.py +++ b/app/playlistmodel.py @@ -399,6 +399,26 @@ class PlaylistModel(QAbstractTableModel): return QVariant() + def get_duplicate_rows(self) -> List[int]: + """ + Return a list of duplicate rows. If track appears in rows 2, 3 and 4, return [3, 4] + (ie, ignore the first, not-yet-duplicate, track). + """ + + found = [] + result = [] + + for i in range(len(self.playlist_rows)): + track_id = self.playlist_rows[i].track_id + if track_id is None: + continue + if track_id in found: + result.append(i) + else: + found.append(track_id) + + return result + def edit_role(self, row: int, column: int, prd: PlaylistRowData) -> QVariant: """ Return text for editing diff --git a/app/playlists.py b/app/playlists.py index 863deda..264a6fe 100644 --- a/app/playlists.py +++ b/app/playlists.py @@ -917,6 +917,26 @@ class PlaylistTab(QTableView): # if match_row is not None: # self.selectRow(row_number) + def select_duplicate_rows(self) -> None: + """ + Select the last of any rows with duplicate tracks in current playlist. + This allows the selection to typically come towards the end of the playlist away + from any show specific sections. + """ + + # Clear any selected rows to avoid confustion + self.clear_selection() + # We need to be in MultiSelection mode + self.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection) + # Get the duplicate rows + model = cast(PlaylistModel, self.model()) + duplicate_rows = model.get_duplicate_rows() + # Select the rows + for duplicate_row in duplicate_rows: + self.selectRow(duplicate_row) + # Reset selection mode + self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) + def selectionChanged( self, selected: QItemSelection, deselected: QItemSelection ) -> None: