parent
f35b8b93b1
commit
d57ffbdb09
@ -22,6 +22,8 @@ from typing import (
|
|||||||
Sequence,
|
Sequence,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from sqlalchemy import text
|
||||||
|
|
||||||
from PyQt6.QtCore import (
|
from PyQt6.QtCore import (
|
||||||
pyqtSignal,
|
pyqtSignal,
|
||||||
QDate,
|
QDate,
|
||||||
@ -668,6 +670,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
lambda: self.tabPlaylist.currentWidget().lookup_row_in_wikipedia()
|
lambda: self.tabPlaylist.currentWidget().lookup_row_in_wikipedia()
|
||||||
)
|
)
|
||||||
self.actionSearch.triggered.connect(self.search_playlist)
|
self.actionSearch.triggered.connect(self.search_playlist)
|
||||||
|
self.actionSelect_duplicate_rows.triggered.connect(self.select_duplicate_rows)
|
||||||
self.actionSelect_next_track.triggered.connect(self.select_next_row)
|
self.actionSelect_next_track.triggered.connect(self.select_next_row)
|
||||||
self.actionSelect_previous_track.triggered.connect(self.select_previous_row)
|
self.actionSelect_previous_track.triggered.connect(self.select_previous_row)
|
||||||
self.actionMoveUnplayed.triggered.connect(self.move_unplayed)
|
self.actionMoveUnplayed.triggered.connect(self.move_unplayed)
|
||||||
@ -1487,6 +1490,31 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.visible_playlist_tab().set_search(self.txtSearch.text())
|
self.visible_playlist_tab().set_search(self.txtSearch.text())
|
||||||
self.enable_play_next_controls()
|
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.visible_playlist_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.visible_playlist_tab().select_rows(row_numbers)
|
||||||
|
self.statusbar.showMessage(f"{len(row_numbers)} duplicate rows selected", 10000)
|
||||||
|
|
||||||
def select_next_row(self) -> None:
|
def select_next_row(self) -> None:
|
||||||
"""Select next or first row in playlist"""
|
"""Select next or first row in playlist"""
|
||||||
|
|
||||||
|
|||||||
@ -979,6 +979,21 @@ class PlaylistTab(QTableWidget):
|
|||||||
|
|
||||||
self.selectRow(row_number)
|
self.selectRow(row_number)
|
||||||
|
|
||||||
|
def select_rows(self, rows: List[int]) -> None:
|
||||||
|
"""
|
||||||
|
Select rows that are passed
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Clear any selected rows to avoid confustion
|
||||||
|
self.clear_selection()
|
||||||
|
# We need to be in MultiSelection mode
|
||||||
|
self.setSelectionMode(QAbstractItemView.SelectionMode.MultiSelection)
|
||||||
|
# Select the rows
|
||||||
|
for row in rows:
|
||||||
|
self.selectRow(row)
|
||||||
|
# Reset selection mode
|
||||||
|
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
|
||||||
|
|
||||||
def tab_visible(self) -> None:
|
def tab_visible(self) -> None:
|
||||||
"""Called when tab becomes visible"""
|
"""Called when tab becomes visible"""
|
||||||
|
|
||||||
|
|||||||
@ -746,6 +746,8 @@ padding-left: 8px;</string>
|
|||||||
<addaction name="actionDeletePlaylist"/>
|
<addaction name="actionDeletePlaylist"/>
|
||||||
<addaction name="actionExport_playlist"/>
|
<addaction name="actionExport_playlist"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionSelect_duplicate_rows"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionMoveSelected"/>
|
<addaction name="actionMoveSelected"/>
|
||||||
<addaction name="actionMoveUnplayed"/>
|
<addaction name="actionMoveUnplayed"/>
|
||||||
<addaction name="actionDownload_CSV_of_played_tracks"/>
|
<addaction name="actionDownload_CSV_of_played_tracks"/>
|
||||||
@ -1132,6 +1134,11 @@ padding-left: 8px;</string>
|
|||||||
<string>Ctrl+S</string>
|
<string>Ctrl+S</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionSelect_duplicate_rows">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select duplicate rows...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# Form implementation generated from reading ui file 'app/ui/main_window.ui'
|
# Form implementation generated from reading ui file 'app/ui/main_window.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt6 UI code generator 6.5.2
|
# Created by: PyQt6 UI code generator 6.5.3
|
||||||
#
|
#
|
||||||
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
|
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
|
||||||
# run again. Do not edit this file unless you know what you are doing.
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
@ -453,6 +453,8 @@ class Ui_MainWindow(object):
|
|||||||
self.actionSearch_title_in_Wikipedia.setObjectName("actionSearch_title_in_Wikipedia")
|
self.actionSearch_title_in_Wikipedia.setObjectName("actionSearch_title_in_Wikipedia")
|
||||||
self.actionSearch_title_in_Songfacts = QtGui.QAction(parent=MainWindow)
|
self.actionSearch_title_in_Songfacts = QtGui.QAction(parent=MainWindow)
|
||||||
self.actionSearch_title_in_Songfacts.setObjectName("actionSearch_title_in_Songfacts")
|
self.actionSearch_title_in_Songfacts.setObjectName("actionSearch_title_in_Songfacts")
|
||||||
|
self.actionSelect_duplicate_rows = QtGui.QAction(parent=MainWindow)
|
||||||
|
self.actionSelect_duplicate_rows.setObjectName("actionSelect_duplicate_rows")
|
||||||
self.menuFile.addAction(self.actionNewPlaylist)
|
self.menuFile.addAction(self.actionNewPlaylist)
|
||||||
self.menuFile.addAction(self.actionNew_from_template)
|
self.menuFile.addAction(self.actionNew_from_template)
|
||||||
self.menuFile.addAction(self.actionOpenPlaylist)
|
self.menuFile.addAction(self.actionOpenPlaylist)
|
||||||
@ -461,6 +463,8 @@ class Ui_MainWindow(object):
|
|||||||
self.menuFile.addAction(self.actionDeletePlaylist)
|
self.menuFile.addAction(self.actionDeletePlaylist)
|
||||||
self.menuFile.addAction(self.actionExport_playlist)
|
self.menuFile.addAction(self.actionExport_playlist)
|
||||||
self.menuFile.addSeparator()
|
self.menuFile.addSeparator()
|
||||||
|
self.menuFile.addAction(self.actionSelect_duplicate_rows)
|
||||||
|
self.menuFile.addSeparator()
|
||||||
self.menuFile.addAction(self.actionMoveSelected)
|
self.menuFile.addAction(self.actionMoveSelected)
|
||||||
self.menuFile.addAction(self.actionMoveUnplayed)
|
self.menuFile.addAction(self.actionMoveUnplayed)
|
||||||
self.menuFile.addAction(self.actionDownload_CSV_of_played_tracks)
|
self.menuFile.addAction(self.actionDownload_CSV_of_played_tracks)
|
||||||
@ -595,5 +599,6 @@ class Ui_MainWindow(object):
|
|||||||
self.actionSearch_title_in_Wikipedia.setShortcut(_translate("MainWindow", "Ctrl+W"))
|
self.actionSearch_title_in_Wikipedia.setShortcut(_translate("MainWindow", "Ctrl+W"))
|
||||||
self.actionSearch_title_in_Songfacts.setText(_translate("MainWindow", "Search title in Songfacts"))
|
self.actionSearch_title_in_Songfacts.setText(_translate("MainWindow", "Search title in Songfacts"))
|
||||||
self.actionSearch_title_in_Songfacts.setShortcut(_translate("MainWindow", "Ctrl+S"))
|
self.actionSearch_title_in_Songfacts.setShortcut(_translate("MainWindow", "Ctrl+S"))
|
||||||
|
self.actionSelect_duplicate_rows.setText(_translate("MainWindow", "Select duplicate rows..."))
|
||||||
from infotabs import InfoTabs
|
from infotabs import InfoTabs
|
||||||
from pyqtgraph import PlotWidget
|
from pyqtgraph import PlotWidget
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user