Add ability to delete and rename playlists

Fixes #54
This commit is contained in:
Keith Edmunds 2023-02-13 19:34:28 +00:00
parent 2a6dfc8b63
commit 8476dd4ace
4 changed files with 75 additions and 20 deletions

View File

@ -249,6 +249,14 @@ class Playlists(Base):
return playlist
def delete(self, session: scoped_session) -> None:
"""
Mark as deleted
"""
self.deleted = True
session.flush()
@classmethod
def get_all(cls, session: scoped_session) -> List["Playlists"]:
"""Returns a list of all playlists ordered by last use"""
@ -286,7 +294,8 @@ class Playlists(Base):
select(cls)
.filter(
cls.tab.is_(None),
cls.is_template.is_(False)
cls.is_template.is_(False),
cls.deleted.is_(False)
)
.order_by(cls.last_used.desc())
)
@ -336,6 +345,14 @@ class Playlists(Base):
row_to.tab = frm
row_frm.tab = to
def rename(self, session: scoped_session, new_name: str) -> None:
"""
Rename playlist
"""
self.name = new_name
session.flush()
@staticmethod
def save_as_template(session: scoped_session,
playlist_id: int, template_name: str) -> None:

View File

@ -491,17 +491,19 @@ class Window(QMainWindow, Ui_MainWindow):
event.accept()
def close_playlist_tab(self) -> None:
def close_playlist_tab(self) -> bool:
"""
Close active playlist tab, called by menu item
"""
self.close_tab(self.tabPlaylist.currentIndex())
return self.close_tab(self.tabPlaylist.currentIndex())
def close_tab(self, tab_index: int) -> None:
def close_tab(self, tab_index: int) -> bool:
"""
Close playlist tab unless it holds the current or next track.
Called from close_playlist_tab() or by clicking close button on tab.
Return True if tab closed else False.
"""
# Don't close current track playlist
@ -509,13 +511,13 @@ class Window(QMainWindow, Ui_MainWindow):
self.current_track.playlist_tab):
self.statusbar.showMessage(
"Can't close current track playlist", 5000)
return
return False
# Don't close next track playlist
if self.tabPlaylist.widget(tab_index) == self.next_track.playlist_tab:
self.statusbar.showMessage(
"Can't close next track playlist", 5000)
return
return False
# Record playlist as closed and update remaining playlist tabs
with Session() as session:
@ -528,11 +530,14 @@ class Window(QMainWindow, Ui_MainWindow):
self.tabPlaylist.widget(tab_index).close()
self.tabPlaylist.removeTab(tab_index)
return True
def connect_signals_slots(self) -> None:
self.action_About.triggered.connect(self.about)
self.action_Clear_selection.triggered.connect(self.clear_selection)
self.actionDebug.triggered.connect(self.debug)
self.actionClosePlaylist.triggered.connect(self.close_playlist_tab)
self.actionDeletePlaylist.triggered.connect(self.delete_playlist)
self.actionDownload_CSV_of_played_tracks.triggered.connect(
self.download_played_tracks)
self.actionEnable_controls.triggered.connect(
@ -553,6 +558,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.actionOpenPlaylist.triggered.connect(self.open_playlist)
self.actionPaste.triggered.connect(self.paste_rows)
self.actionPlay_next.triggered.connect(self.play_next)
self.actionRenamePlaylist.triggered.connect(self.rename_playlist)
self.actionResume.triggered.connect(self.resume)
self.actionSave_as_template.triggered.connect(self.save_as_template)
self.actionSearch.triggered.connect(self.search_playlist)
@ -630,6 +636,22 @@ class Window(QMainWindow, Ui_MainWindow):
import ipdb # type: ignore
ipdb.set_trace()
def delete_playlist(self) -> None:
"""
Delete current playlist
"""
with Session() as session:
playlist_id = self.visible_playlist_tab().playlist_id
playlist = session.get(Playlists, playlist_id)
if playlist:
if helpers.ask_yes_no("Delete playlist",
f"Delete playlist '{playlist.name}': "
"Are you sure?"
):
if self.close_playlist_tab():
playlist.delete(session)
def disable_play_next_controls(self) -> None:
"""
Disable "play next" keyboard controls
@ -1253,6 +1275,21 @@ class Window(QMainWindow, Ui_MainWindow):
self.current_track.end_time.strftime(
Config.TRACK_TIME_FORMAT))
def rename_playlist(self) -> None:
"""
Rename current playlist
"""
with Session() as session:
playlist_id = self.visible_playlist_tab().playlist_id
playlist = session.get(Playlists, playlist_id)
if playlist:
new_name = self.solicit_playlist_name(playlist.name)
if new_name:
playlist.rename(session, new_name)
idx = self.tabBar.currentIndex()
self.tabBar.setTabText(idx, new_name)
def resume(self) -> None:
"""
Resume playing stopped track
@ -1400,12 +1437,15 @@ class Window(QMainWindow, Ui_MainWindow):
self.tabPlaylist.setCurrentWidget(self.next_track.playlist_tab)
self.tabPlaylist.currentWidget().scroll_next_to_top()
def solicit_playlist_name(self) -> Optional[str]:
def solicit_playlist_name(self,
default: Optional[str] = "") -> Optional[str]:
"""Get name of playlist from user"""
dlg = QInputDialog(self)
dlg.setInputMode(QInputDialog.TextInput)
dlg.setLabelText("Playlist name:")
if default:
dlg.setTextValue(default)
dlg.resize(500, 100)
ok = dlg.exec()
if ok:

View File

@ -831,18 +831,17 @@ padding-left: 8px;</string>
<string>&amp;Playlists</string>
</property>
<addaction name="actionNewPlaylist"/>
<addaction name="actionNew_from_template"/>
<addaction name="actionOpenPlaylist"/>
<addaction name="actionClosePlaylist"/>
<addaction name="actionRenamePlaylist"/>
<addaction name="actionExport_playlist"/>
<addaction name="actionDeletePlaylist"/>
<addaction name="separator"/>
<addaction name="actionNew_from_template"/>
<addaction name="actionSave_as_template"/>
<addaction name="actionExport_playlist"/>
<addaction name="separator"/>
<addaction name="actionMoveSelected"/>
<addaction name="actionMoveUnplayed"/>
<addaction name="actionDownload_CSV_of_played_tracks"/>
<addaction name="actionSave_as_template"/>
<addaction name="separator"/>
<addaction name="actionE_xit"/>
</widget>
@ -1036,7 +1035,7 @@ padding-left: 8px;</string>
</action>
<action name="actionRenamePlaylist">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Rename...</string>
@ -1044,7 +1043,7 @@ padding-left: 8px;</string>
</action>
<action name="actionDeletePlaylist">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="text">
<string>Dele&amp;te...</string>

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'app/ui/main_window.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
@ -452,10 +452,10 @@ class Ui_MainWindow(object):
self.actionClosePlaylist.setEnabled(True)
self.actionClosePlaylist.setObjectName("actionClosePlaylist")
self.actionRenamePlaylist = QtWidgets.QAction(MainWindow)
self.actionRenamePlaylist.setEnabled(False)
self.actionRenamePlaylist.setEnabled(True)
self.actionRenamePlaylist.setObjectName("actionRenamePlaylist")
self.actionDeletePlaylist = QtWidgets.QAction(MainWindow)
self.actionDeletePlaylist.setEnabled(False)
self.actionDeletePlaylist.setEnabled(True)
self.actionDeletePlaylist.setObjectName("actionDeletePlaylist")
self.actionMoveSelected = QtWidgets.QAction(MainWindow)
self.actionMoveSelected.setObjectName("actionMoveSelected")
@ -506,18 +506,17 @@ class Ui_MainWindow(object):
self.actionResume = QtWidgets.QAction(MainWindow)
self.actionResume.setObjectName("actionResume")
self.menuFile.addAction(self.actionNewPlaylist)
self.menuFile.addAction(self.actionNew_from_template)
self.menuFile.addAction(self.actionOpenPlaylist)
self.menuFile.addAction(self.actionClosePlaylist)
self.menuFile.addAction(self.actionRenamePlaylist)
self.menuFile.addAction(self.actionExport_playlist)
self.menuFile.addAction(self.actionDeletePlaylist)
self.menuFile.addSeparator()
self.menuFile.addAction(self.actionNew_from_template)
self.menuFile.addAction(self.actionSave_as_template)
self.menuFile.addAction(self.actionExport_playlist)
self.menuFile.addSeparator()
self.menuFile.addAction(self.actionMoveSelected)
self.menuFile.addAction(self.actionMoveUnplayed)
self.menuFile.addAction(self.actionDownload_CSV_of_played_tracks)
self.menuFile.addAction(self.actionSave_as_template)
self.menuFile.addSeparator()
self.menuFile.addAction(self.actionE_xit)
self.menuPlaylist.addSeparator()