diff --git a/app/models.py b/app/models.py
index 6a02ae9..efe6f45 100644
--- a/app/models.py
+++ b/app/models.py
@@ -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:
diff --git a/app/musicmuster.py b/app/musicmuster.py
index f77ea54..21692fb 100755
--- a/app/musicmuster.py
+++ b/app/musicmuster.py
@@ -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:
diff --git a/app/ui/main_window.ui b/app/ui/main_window.ui
index 9e2c7b5..3e510bd 100644
--- a/app/ui/main_window.ui
+++ b/app/ui/main_window.ui
@@ -831,18 +831,17 @@ padding-left: 8px;
&Playlists
+
-
-
-
-
+
+
@@ -1036,7 +1035,7 @@ padding-left: 8px;
- false
+ true
&Rename...
@@ -1044,7 +1043,7 @@ padding-left: 8px;
- false
+ true
Dele&te...
diff --git a/app/ui/main_window_ui.py b/app/ui/main_window_ui.py
index 7338d49..ae265cd 100644
--- a/app/ui/main_window_ui.py
+++ b/app/ui/main_window_ui.py
@@ -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()