Commit 2a39a269 authored by Jean Felder's avatar Jean Felder Committed by Marinus Schraal

playlistsview: Restore playlist deletion

parent 4f46a052
......@@ -151,3 +151,24 @@ class CoreGrilo(GObject.GObject):
if "grl-tracker-source" not in self._wrappers:
self._wrappers["grl-tracker-source"].get_album_art_for_item(
coresong, callback)
def stage_playlist_deletion(self, playlist):
"""Prepares playlist deletion.
:param Playlist playlist: playlist
"""
for wrapper in self._wrappers:
if wrapper.source.props.source_id == "grl-tracker-source":
wrapper.stage_playlist_deletion(playlist)
break
def finish_playlist_deletion(self, playlist, deleted):
"""Finishes playlist deletion.
:param Playlist playlist: playlist
:param bool deleted: indicates if the playlist has been deleted
"""
for wrapper in self._wrappers:
if wrapper.source.props.source_id == "grl-tracker-source":
wrapper.finish_playlist_deletion(playlist, deleted)
break
......@@ -272,6 +272,29 @@ class CoreModel(GObject.GObject):
self.emit("playlist-loaded")
def stage_playlist_deletion(self, playlist):
"""Prepares playlist deletion.
:param Playlist playlist: playlist
"""
self._grilo.stage_playlist_deletion(playlist)
def finish_playlist_deletion(self, playlist, deleted):
"""Finishes playlist deletion.
:param Playlist playlist: playlist
:param bool deleted: indicates if the playlist has been deleted
"""
self._grilo.finish_playlist_deletion(playlist, deleted)
def create_playlist(self, playlist_title, callback):
"""Creates a new user playlist.
:param str playlist_title: playlist title
:param callback: function to perform once, the playlist is created
"""
self._grilo.create_playlist(playlist_title, callback)
def search(self, text):
self._grilo.search(text)
......@@ -352,3 +375,9 @@ class CoreModel(GObject.GObject):
flags=GObject.ParamFlags.READABLE)
def playlists_sort(self):
return self._playlists_model_sort
@GObject.Property(
type=Gfm.SortListModel, default=None,
flags=GObject.ParamFlags.READABLE)
def playlists_filter(self):
return self._playlists_model_filter
......@@ -41,6 +41,9 @@ class GrlTrackerPlaylists(GObject.GObject):
self._grilo = grilo
self._source = source
self._model = self._coremodel.props.playlists
self._model_filter = self._coremodel.props.playlists_filter
self._pls_todelete = []
self._tracker = TrackerWrapper().props.tracker
self._fast_options = Grl.OperationOptions()
self._fast_options.set_resolution_flags(
......@@ -105,6 +108,60 @@ class GrlTrackerPlaylists(GObject.GObject):
self._model.append(playlist)
def _playlists_filter(self, playlist):
return playlist not in self._pls_todelete
def stage_playlist_deletion(self, playlist):
"""Adds playlist to the list of playlists to delete
:param Playlist playlist: playlist
"""
self._pls_todelete.append(playlist)
self._model_filter.set_filter_func(self._playlists_filter)
def finish_playlist_deletion(self, playlist, deleted):
"""Removes playlist from the list of playlists to delete
:param Playlist playlist: playlist
:param bool deleted: indicates if the playlist has been deleted
"""
self._pls_todelete.remove(playlist)
if deleted is False:
self._model_filter.set_filter_func(self._playlists_filter)
return
def _delete_cb(conn, res, data):
# FIXME: Check for failure.
conn.update_finish(res)
for idx, playlist_model in enumerate(self._model):
if playlist_model is playlist:
self._model.remove(idx)
break
self._model_filter.set_filter_func(self._playlists_filter)
query = """
DELETE {
?playlist a rdfs:Resource .
?entry a rdfs:Resource .
}
WHERE {
?playlist a nmm:Playlist ;
a nfo:MediaList .
OPTIONAL {
?playlist nfo:hasMediaFileListEntry ?entry .
}
FILTER (
tracker:id(?playlist) = %(playlist_id)s
)
}
""".replace("\n", " ").strip() % {
"playlist_id": playlist.props.pl_id
}
self._tracker.update_async(
query, GLib.PRIORITY_LOW, None, _delete_cb, None)
class Playlist(GObject.GObject):
""" Base class of all playlists """
......@@ -265,7 +322,7 @@ class Playlist(GObject.GObject):
self._tracker.update_async(
query, GLib.PRIORITY_LOW, None, update_cb, None)
def stage_deletion(self, coresong, index):
def stage_song_deletion(self, coresong, index):
"""Adds a song to the list of songs to delete
:param CoreSong coresong: song to delete
......@@ -275,8 +332,8 @@ class Playlist(GObject.GObject):
self._model.remove(index)
self.props.count -= 1
def undo_pending_deletion(self, coresong, position):
"""Adds a song to the list of songs to delete
def undo_pending_song_deletion(self, coresong, position):
"""Removes song from the list of songs to delete
:param CoreSong coresong: song to delete
:param int position: Song position in the playlist
......@@ -285,7 +342,7 @@ class Playlist(GObject.GObject):
self._model.insert(position, coresong)
self.props.count += 1
def finish_deletion(self, coresong):
def finish_song_deletion(self, coresong):
"""Removes a song from the playlist
:param CoreSong coresong: song to remove
......
......@@ -64,7 +64,8 @@ class GrlTrackerSource(GObject.GObject):
self._initial_albums_fill(self._source)
self._initial_artists_fill(self._source)
GrlTrackerPlaylists(source, coremodel, coreselection, grilo)
self._tracker_playlists = GrlTrackerPlaylists(
source, coremodel, coreselection, grilo)
self._source.notify_change_start()
self._source.connect("content-changed", self._on_content_changed)
......@@ -724,3 +725,26 @@ class GrlTrackerSource(GObject.GObject):
}
return query
def stage_playlist_deletion(self, playlist):
"""Prepares playlist deletion.
:param Playlist playlist: playlist
"""
self._tracker_playlists.stage_playlist_deletion(playlist)
def finish_playlist_deletion(self, playlist, deleted):
"""Finishes playlist deletion.
:param Playlist playlist: playlist
:param bool deleted: indicates if the playlist has been deleted
"""
self._tracker_playlists.finish_playlist_deletion(playlist, deleted)
def create_playlist(self, playlist_title, callback):
"""Creates a new user playlist.
:param str playlist_title: playlist title
:param callback: function to perform once, the playlist is created
"""
self._tracker_playlists.create_playlist(playlist_title, callback)
......@@ -90,11 +90,12 @@ class PlaylistsView(BaseView):
'activate', self._on_play_playlist)
self._window.add_action(playlist_play_action)
# self._playlist_delete_action = Gio.SimpleAction.new(
# 'playlist_delete', None)
# self._playlist_delete_action.connect(
# 'activate', self._stage_playlist_for_deletion)
# self._window.add_action(self._playlist_delete_action)
self._playlist_delete_action = Gio.SimpleAction.new(
'playlist_delete', None)
self._playlist_delete_action.connect(
'activate', self._stage_playlist_for_deletion)
self._window.add_action(self._playlist_delete_action)
self._playlist_rename_action = Gio.SimpleAction.new(
'playlist_rename', None)
self._playlist_rename_action.connect(
......@@ -207,8 +208,9 @@ class PlaylistsView(BaseView):
selected_playlist = self._sidebar.get_selected_row().playlist
notification = PlaylistNotification( # noqa: F841
self._window.notifications_popup, PlaylistNotification.Type.SONG,
selected_playlist, coresong, position)
self._window.notifications_popup, self._coremodel,
PlaylistNotification.Type.SONG, selected_playlist, position,
coresong)
@log
def _on_playlist_activated(self, sidebar, row, data=None):
......@@ -227,6 +229,7 @@ class PlaylistsView(BaseView):
playlist.connect("notify::count", self._on_song_count_changed)
self._playlist_rename_action.set_enabled(not playlist.props.is_smart)
self._playlist_delete_action.set_enabled(not playlist.props.is_smart)
def _on_song_count_changed(self, playlist, value):
self._update_songs_count(playlist.props.count)
......@@ -271,6 +274,22 @@ class PlaylistsView(BaseView):
pl_torename = selection.playlist
pl_torename.rename(new_name)
@log
def _stage_playlist_for_deletion(self, menutime, data=None):
selected_row = self._sidebar.get_selected_row()
selected_playlist = selected_row.playlist
notification = PlaylistNotification( # noqa: F841
self._window.notifications_popup, self._coremodel,
PlaylistNotification.Type.PLAYLIST, selected_playlist)
# FIXME: Should Check that the playlist is not playing
# playlist_id = selection.playlist.props.pl_id
# if self.player.playing_playlist(
# PlayerPlaylist.Type.PLAYLIST, playlist_id):
# self.player.stop()
# self._window.set_player_visible(False)
@log
def _populate(self, data=None):
"""Populate sidebar.
......
......@@ -213,21 +213,25 @@ class PlaylistNotification(Gtk.Grid):
return '<PlaylistNotification>'
@log
def __init__(self, notifications_popup, type_, playlist, data, position):
def __init__(
self, notifications_popup, coremodel, type_, playlist,
position=None, coresong=None):
"""Creates a playlist deletion notification popup (song or playlist)
:param GtkRevealer notifications_popup: the popup object
:param GtkRevealer: notifications_popup: the popup object
:param CoreModel: core model
:param type_: NotificationType (song or playlist)
:param Playlist playlist: playlist
:param object data: Data associated with the deletion
:param int position: position of the object to delete
:param object coresong: CoreSong for song deletion
"""
super().__init__(column_spacing=18)
self._notifications_popup = notifications_popup
self._coremodel = coremodel
self.type_ = type_
self._playlist = playlist
self.data = data
self._position = position
self._coresong = coresong
message = self._create_notification_message()
self._label = Gtk.Label(
......@@ -239,25 +243,24 @@ class PlaylistNotification(Gtk.Grid):
self.add(undo_button)
self.show_all()
if self.type_ == PlaylistNotification.Type.SONG:
playlist.stage_deletion(self.data, position)
if self.type_ == PlaylistNotification.Type.PLAYLIST:
self._coremodel.stage_playlist_deletion(self._playlist)
else:
playlist.stage_song_deletion(self._coresong, position)
self._timeout_id = GLib.timeout_add_seconds(5, self._finish_deletion)
self._notifications_popup.add_notification(self)
def _create_notification_message(self):
if self.type_ == PlaylistNotification.Type.PLAYLIST:
return None
# pl_todelete = data
# msg = _("Playlist {} removed".format(pl_todelete.props.title))
msg = _("Playlist {} removed".format(self._playlist.props.title))
else:
playlist_title = self._playlist.props.title
coresong = self.data
song_title = coresong.props.title
song_title = self._coresong.props.title
msg = _("{} removed from {}".format(
song_title, playlist_title))
return msg
return msg
@log
def _undo_deletion(self, widget_):
......@@ -267,8 +270,15 @@ class PlaylistNotification(Gtk.Grid):
self._timeout_id = 0
self._notifications_popup.remove_notification(self)
self._playlist.undo_pending_deletion(self.data, self._position)
if self.type_ == PlaylistNotification.Type.PLAYLIST:
self._coremodel.finish_playlist_deletion(self._playlist, False)
else:
self._playlist.undo_pending_song_deletion(
self._coresong, self._position)
def _finish_deletion(self):
self._notifications_popup.remove_notification(self)
self._playlist.finish_deletion(self.data)
if self.type_ == PlaylistNotification.Type.PLAYLIST:
self._coremodel.finish_playlist_deletion(self._playlist, True)
else:
self._playlist.finish_song_deletion(self._coresong)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment