Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: support create/delete playlist #731

Merged
merged 4 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions feeluown/gui/uimain/sidebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
from PyQt5.QtWidgets import QFrame, QLabel, QVBoxLayout, QSizePolicy, QScrollArea, \
QHBoxLayout, QFormLayout, QDialog, QLineEdit, QDialogButtonBox, QMessageBox

from feeluown.library import SupportsPlaylistDelete
from feeluown.collection import CollectionAlreadyExists, CollectionType
from feeluown.utils import aio
from feeluown.gui.provider_ui import UISupportsCreatePlaylist
from feeluown.gui.widgets import (
DiscoveryButton, HomeButton, PlusButton, TriagleButton,
)
Expand Down Expand Up @@ -153,9 +156,12 @@ def __init__(self, app: 'GuiApp', parent=None):
lambda pl: self._app.browser.goto(model=pl))
self.collections_view.show_collection.connect(
lambda coll: self._app.browser.goto(page=f'/colls/{coll.identifier}'))
self.collections_view.remove_collection.connect(self.remove_coll)
self.collections_view.remove_collection.connect(self._remove_coll)
self.playlists_view.remove_playlist.connect(self._remove_playlist)
self.collections_con.create_btn.clicked.connect(
self.popup_collection_adding_dialog)
self.playlists_con.create_btn.clicked.connect(
self.popup_playlist_adding_dialog)

def popup_collection_adding_dialog(self):
dialog = QDialog(self)
Expand Down Expand Up @@ -184,6 +190,12 @@ def create_collection_and_reload():
dialog.accepted.connect(create_collection_and_reload)
dialog.open()

def popup_playlist_adding_dialog(self):
provider_ui = self._app.current_pvd_ui_mgr.get()
if provider_ui is not None:
if isinstance(provider_ui, UISupportsCreatePlaylist):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以把 CreatePlaylist 变成 CreatePlaylistWithName,这样就可以更好的共享代码了

provider_ui.popup_create_playlist_dialog()

def show_library(self):
coll_library = self._app.coll_mgr.get_coll_library()
self._app.browser.goto(page=f'/colls/{coll_library.identifier}')
Expand All @@ -192,7 +204,23 @@ def show_pool(self):
coll = self._app.coll_mgr.get(CollectionType.sys_pool)
self._app.browser.goto(page=f'/colls/{coll.identifier}')

def remove_coll(self, coll):
def _remove_playlist(self, playlist):
async def do():
provider = self._app.library.get_or_raise(playlist.source)
if isinstance(provider, SupportsPlaylistDelete):
ok = await aio.run_fn(provider.playlist_delete, playlist.identifier)
self._app.show_msg(f"删除歌单 {playlist.name} {'成功' if ok else '失败'}")
if ok is True:
self._app.pl_uimgr.model.remove(playlist)
else:
self._app.show_msg(f'资源提供方({provider.identifier})不支持删除歌单')

box = QMessageBox(QMessageBox.Warning, '提示', f"确认删除歌单 '{playlist.name}' 吗?",
QMessageBox.Yes | QMessageBox.No, self)
box.accepted.connect(lambda: aio.run_afn(do))
box.open()

def _remove_coll(self, coll):
def do():
self._app.coll_mgr.remove(coll)
self._app.coll_mgr.refresh()
Expand Down
31 changes: 30 additions & 1 deletion feeluown/gui/widgets/playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
QModelIndex,
)
from PyQt5.QtWidgets import (
QAbstractItemView,
QAbstractItemView, QMenu
)

from .textlist import TextlistModel, TextlistView
Expand Down Expand Up @@ -42,6 +42,23 @@ def add(self, playlist, is_fav=False):
playlists.extend(_playlists)
self.endInsertRows()

def remove(self, playlist):
for i, playlist_ in enumerate(self._playlists):
if playlist_ == playlist:
self.beginRemoveRows(QModelIndex(), i, i+1)
self._playlists.remove(playlist)
self.endRemoveRows()
break

for i, playlist_ in enumerate(self._fav_playlists):
if playlist_ == playlist:
start = i+len(self._playlists)
end = start + 1
self.beginRemoveRows(QModelIndex(), start, end)
self._fav_playlists.remove(playlist)
self.endRemoveRows()
break

def clear(self):
total_length = len(self.items)
self.beginRemoveRows(QModelIndex(), 0, total_length - 1)
Expand Down Expand Up @@ -77,6 +94,7 @@ class PlaylistsView(TextlistView):
.. versiondeprecated:: 3.9
"""
show_playlist = pyqtSignal([object])
remove_playlist = pyqtSignal([object])

def __init__(self, parent):
super().__init__(parent)
Expand All @@ -88,6 +106,17 @@ def _on_clicked(self, index):
playlist = index.data(role=Qt.UserRole)
self.show_playlist.emit(playlist)

def contextMenuEvent(self, event):
indexes = self.selectionModel().selectedIndexes()
if len(indexes) != 1:
return

playlist = self.model().data(indexes[0], Qt.UserRole)
menu = QMenu()
action = menu.addAction('删除此歌单')
action.triggered.connect(lambda: self.remove_playlist.emit(playlist))
menu.exec(event.globalPos())

def dropEvent(self, e):
mimedata = e.mimeData()
song = mimedata.model
Expand Down
12 changes: 12 additions & 0 deletions feeluown/library/provider_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

'SupportsPlaylistAddSong',
'SupportsPlaylistGet',
'SupportsPlaylistDelete',
'SupportsPlaylistRemoveSong',
'SupportsPlaylistSongsReader',

Expand Down Expand Up @@ -280,6 +281,17 @@ def playlist_get(self, identifier: ID) -> PlaylistModel:
raise NotImplementedError


@runtime_checkable
class SupportsPlaylistDelete(Protocol):
@abstractmethod
def playlist_delete(self, identifier: ID) -> bool:
"""
:raises ModelNotFound: model not found by the identifier
:raises ProviderIOError:
"""
raise NotImplementedError


@eq(ModelType.playlist, PF.songs_rd)
@runtime_checkable
class SupportsPlaylistSongsReader(Protocol):
Expand Down
Loading