[gnome-music] notificationspopup: Create NotificationsPopup



commit 25dfb0d012b503a5ee5329b91c619a13e6703f92
Author: Jean Felder <jean felder gmail com>
Date:   Tue Jan 30 02:34:58 2018 +0100

    notificationspopup: Create NotificationsPopup
    
    Handle loading and playlist removal notifications.
    Add the possibility to remove multiple playlists independently.
    Remove all notification code from window.py.

 gnomemusic/views/albumsview.py           |   6 +-
 gnomemusic/views/artistsview.py          |   4 +-
 gnomemusic/views/baseview.py             |   2 +-
 gnomemusic/views/playlistview.py         |  45 +++---
 gnomemusic/views/searchview.py           |   4 +-
 gnomemusic/views/songsview.py            |   4 +-
 gnomemusic/widgets/Makefile.am           |   1 +
 gnomemusic/widgets/artistalbumswidget.py |   4 +-
 gnomemusic/widgets/notificationspopup.py | 234 +++++++++++++++++++++++++++++++
 gnomemusic/widgets/playlistdialog.py     |   9 +-
 gnomemusic/window.py                     | 133 +-----------------
 11 files changed, 284 insertions(+), 162 deletions(-)
---
diff --git a/gnomemusic/views/albumsview.py b/gnomemusic/views/albumsview.py
index 1538a59..8a488ba 100644
--- a/gnomemusic/views/albumsview.py
+++ b/gnomemusic/views/albumsview.py
@@ -120,7 +120,7 @@ class AlbumsView(BaseView):
 
     @log
     def populate(self):
-        self._window.push_loading_notification()
+        self._window.notifications_popup.push_loading()
         grilo.populate_albums(self._offset, self._add_item)
 
     @log
@@ -146,8 +146,8 @@ class AlbumsView(BaseView):
             child = self._create_album_item(item)
             self._view.add(child)
         elif remaining == 0:
-                self._window.pop_loading_notification()
-                self._view.show()
+            self._window.notifications_popup.pop_loading()
+            self._view.show()
 
     def _create_album_item(self, item):
         artist = utils.get_artist_name(item)
diff --git a/gnomemusic/views/artistsview.py b/gnomemusic/views/artistsview.py
index 2154fd8..e63e1c7 100644
--- a/gnomemusic/views/artistsview.py
+++ b/gnomemusic/views/artistsview.py
@@ -165,7 +165,7 @@ class ArtistsView(BaseView):
     def _add_item(self, source, param, item, remaining=0, data=None):
         if (not item and remaining == 0):
             self._view.set_model(self.model)
-            self._window.pop_loading_notification()
+            self._window.notifications_popup.pop_loading()
             self._view.show()
             return
         self._offset += 1
@@ -182,7 +182,7 @@ class ArtistsView(BaseView):
     @log
     def populate(self):
         """Populates the view"""
-        self._window.push_loading_notification()
+        self._window.notifications_popup.push_loading()
         grilo.populate_artists(self._offset, self._add_item)
 
     @log
diff --git a/gnomemusic/views/baseview.py b/gnomemusic/views/baseview.py
index 8048bf9..2a7c043 100644
--- a/gnomemusic/views/baseview.py
+++ b/gnomemusic/views/baseview.py
@@ -216,7 +216,7 @@ class BaseView(Gtk.Stack):
         if not item:
             if remaining == 0:
                 self._view.set_model(self.model)
-                self._window.pop_loading_notification()
+                self._window.notifications_popup.pop_loading()
                 self._view.show()
             return
         self._offset += 1
diff --git a/gnomemusic/views/playlistview.py b/gnomemusic/views/playlistview.py
index 6cdd839..756b64d 100644
--- a/gnomemusic/views/playlistview.py
+++ b/gnomemusic/views/playlistview.py
@@ -30,6 +30,7 @@ from gnomemusic.grilo import grilo
 from gnomemusic.player import DiscoveryStatus
 from gnomemusic.playlists import Playlists, StaticPlaylists
 from gnomemusic.views.baseview import BaseView
+from gnomemusic.widgets.notificationspopup import PlaylistNotification
 from gnomemusic.widgets.playlistdialog import PlaylistDialog
 import gnomemusic.utils as utils
 
@@ -132,7 +133,7 @@ class PlaylistView(BaseView):
         self._iter_to_clean_model = None
         self._current_playlist = None
         self._current_playlist_index = None
-        self.pl_todelete = {}
+        self.pls_todelete = {}
         self._songs_count = 0
         self._handler_rename_done_button = 0
         self._handler_rename_entry = 0
@@ -267,7 +268,7 @@ class PlaylistView(BaseView):
     @log
     def _populate(self):
         self._init = True
-        self._window.push_loading_notification()
+        self._window.notifications_popup.push_loading()
         self.populate()
 
     @log
@@ -298,7 +299,7 @@ class PlaylistView(BaseView):
         :param data: associated data
         """
         if not playlist:
-            self._window.pop_loading_notification()
+            self._window.notifications_popup.pop_loading()
             self.emit('playlists-loaded')
             return
 
@@ -450,7 +451,7 @@ class PlaylistView(BaseView):
         song = model[_iter][5]
 
         playlist_dialog = PlaylistDialog(
-            self._window, self.pl_todelete.get('playlist'))
+            self._window, self.pls_todelete)
         if playlist_dialog.run() == Gtk.ResponseType.ACCEPT:
             playlists.add_to_playlist(playlist_dialog.get_selected(), [song])
         playlist_dialog.destroy()
@@ -630,23 +631,29 @@ class PlaylistView(BaseView):
         return False
 
     @log
-    def _get_removal_notification_message(self):
-        playlist_title = utils.get_media_title(self.pl_todelete['playlist'])
+    def _get_removal_notification_message(self, playlist_id):
+        pl_todelete = self.pls_todelete[playlist_id]
+        playlist_title = utils.get_media_title(pl_todelete['playlist'])
         msg = _("Playlist {} removed".format(playlist_title))
         return msg
 
     @log
-    def _create_playlist_notification(self):
-        msg = self._get_removal_notification_message()
-        self._window.show_playlist_notification(msg)
+    def _create_playlist_notification(self, playlist_id):
+        msg = self._get_removal_notification_message(playlist_id)
+        playlist_notification = PlaylistNotification(
+            self._window.notifications_popup, msg, playlist_id)
+        playlist_notification.connect(
+            'undo-deletion', self._undo_playlist_deletion)
+        playlist_notification.connect(
+            'finish-deletion', self._finish_playlist_deletion)
 
     @log
     def _stage_playlist_for_deletion(self, menutime, data=None):
-        self._window.show_playlist_notification()
         self.model.clear()
         selection = self._sidebar.get_selected_row()
         index = selection.get_index()
-        self.pl_todelete = {
+        playlist_id = self.current_playlist.get_id()
+        self.pls_todelete[playlist_id] = {
             'playlist': selection.playlist,
             'index': index
         }
@@ -658,17 +665,23 @@ class PlaylistView(BaseView):
             self._sidebar.select_row(row_next)
             self._sidebar.emit('row-activated', row_next)
 
-        self._create_playlist_notification()
+        self._create_playlist_notification(playlist_id)
 
     @log
-    def undo_playlist_deletion(self):
+    def _undo_playlist_deletion(self, playlist_notification):
         """Revert the last playlist removal"""
+        playlist_id = playlist_notification.playlist_id
+        pl_todelete = self.pls_todelete[playlist_id]
         self._add_playlist_to_sidebar(
-            self.pl_todelete['playlist'], self.pl_todelete['index'])
+            pl_todelete['playlist'], pl_todelete['index'])
+        self.pls_todelete.pop(playlist_id)
 
     @log
-    def finish_playlist_deletion(self):
-        playlists.delete_playlist(self.pl_todelete['playlist'])
+    def _finish_playlist_deletion(self, playlist_notification):
+        playlist_id = playlist_notification.playlist_id
+        pl_todelete = self.pls_todelete[playlist_id]
+        playlists.delete_playlist(pl_todelete['playlist'])
+        self.pls_todelete.pop(playlist_id)
 
     @log
     @property
diff --git a/gnomemusic/views/searchview.py b/gnomemusic/views/searchview.py
index 592ed06..c5467a4 100644
--- a/gnomemusic/views/searchview.py
+++ b/gnomemusic/views/searchview.py
@@ -221,7 +221,7 @@ class SearchView(BaseView):
             self.previous_view = self._window.prev_view
 
         if remaining == 0:
-            self._window.pop_loading_notification()
+            self._window.notifications_popup.pop_loading()
             self._view.show()
 
         if not item or model != self.model:
@@ -318,7 +318,7 @@ class SearchView(BaseView):
     @log
     def populate(self):
         self._init = True
-        self._window.push_loading_notification()
+        self._window.notifications_popup.push_loading()
         self._header_bar.set_state(ToolbarState.MAIN)
 
     @log
diff --git a/gnomemusic/views/songsview.py b/gnomemusic/views/songsview.py
index 623c753..e52a87d 100644
--- a/gnomemusic/views/songsview.py
+++ b/gnomemusic/views/songsview.py
@@ -121,7 +121,7 @@ class SongsView(BaseView):
         """Adds track item to the model"""
         if not item and not remaining:
             self._view.set_model(self.model)
-            self._window.pop_loading_notification()
+            self._window.notifications_popup.pop_loading()
             self._view.show()
             return
 
@@ -237,7 +237,7 @@ class SongsView(BaseView):
         """Populates the view"""
         self._init = True
         if grilo.tracker:
-            self._window.push_loading_notification()
+            self._window.notifications_popup.push_loading()
             GLib.idle_add(grilo.populate_songs, self._offset, self._add_item)
 
     @log
diff --git a/gnomemusic/widgets/Makefile.am b/gnomemusic/widgets/Makefile.am
index e02db58..3b50455 100644
--- a/gnomemusic/widgets/Makefile.am
+++ b/gnomemusic/widgets/Makefile.am
@@ -6,5 +6,6 @@ app_PYTHON = \
        artistalbumswidget.py \
        artistalbumwidget.py \
        disclistboxwidget.py \
+       notificationspopup.py \
        playlistdialog.py \
        starhandlerwidget.py
diff --git a/gnomemusic/widgets/artistalbumswidget.py b/gnomemusic/widgets/artistalbumswidget.py
index c870b2b..21a45d8 100644
--- a/gnomemusic/widgets/artistalbumswidget.py
+++ b/gnomemusic/widgets/artistalbumswidget.py
@@ -84,7 +84,7 @@ class ArtistAlbumsWidget(Gtk.Box):
         self._songs_grid_size_group = Gtk.SizeGroup.new(
             Gtk.SizeGroupMode.HORIZONTAL)
 
-        self._window.push_loading_notification()
+        self._window.notifications_popup.push_loading()
 
         for album in albums:
             is_last_album = False
@@ -114,7 +114,7 @@ class ArtistAlbumsWidget(Gtk.Box):
 
     @log
     def _on_last_album_displayed(self, data=None):
-        self._window.pop_loading_notification()
+        self._window.notifications_popup.pop_loading()
         self.show_all()
 
     @log
diff --git a/gnomemusic/widgets/notificationspopup.py b/gnomemusic/widgets/notificationspopup.py
new file mode 100644
index 0000000..455c6af
--- /dev/null
+++ b/gnomemusic/widgets/notificationspopup.py
@@ -0,0 +1,234 @@
+# Copyright (c) 2018 The GNOME Music Developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music.  This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered.  If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so.  If you do not wish to do so,
+# delete this exception statement from your version.
+
+from gettext import gettext as _
+from gi.repository import GLib, GObject, Gtk
+
+from gnomemusic import log
+
+
+class NotificationsPopup(Gtk.Revealer):
+    """Display notification messages as popups
+
+    There are two types of messages:
+    - loading notification
+    - playlist deletion
+    Messages are arranged under each other
+    """
+
+    def __repr__(self):
+        return '<NotificationsPopup>'
+
+    @log
+    def __init__(self):
+        super().__init__(
+            halign=Gtk.Align.CENTER, valign=Gtk.Align.START,
+            transition_type=Gtk.RevealerTransitionType.SLIDE_DOWN)
+        self._setup_view()
+
+    @log
+    def _setup_view(self):
+        frame = Gtk.Frame()
+        frame.get_style_context().add_class('app-notification')
+        self.add(frame)
+
+        self._grid = Gtk.Grid(
+            row_spacing=6, orientation=Gtk.Orientation.VERTICAL)
+        frame.add(self._grid)
+
+        self._loading_notification = LoadingNotification()
+        self._loading_notification.connect('visible', self._set_visibility)
+        self._loading_notification.connect('invisible', self._set_visibility)
+        self._grid.add(self._loading_notification)
+
+        self.show_all()
+        self._loading_notification.hide()
+
+    @log
+    def _hide_notifications(self, notification, remove):
+        if remove:
+            self._grid.remove(notification)
+        self._loading_notification.hide()
+        self.hide()
+
+    @log
+    def _set_visibility(self, notification, remove=False):
+        """Display or hide Notifications Popup.
+
+        Popup is displayed if a loading is active or if a playlist
+        deletion is in progress.
+        """
+        invisible = ((self._loading_notification._counter == 0)
+                     and (len(self._grid.get_children()) <= 2))
+
+        if not invisible:
+            if remove:
+                self._grid.remove(notification)
+            self.show()
+        else:
+            # notification has to be removed from grid once unreveal is
+            # finished. Otherwise, an empty grid will be unrevealed.
+            duration = self.get_transition_duration()
+            GLib.timeout_add(
+                duration + 100, self._hide_notifications, notification, remove)
+        self.set_reveal_child(not invisible)
+
+    @log
+    def pop_loading(self):
+        """Decrease loading notification counter.
+
+        If it reaches zero, the notification is withdrawn.
+        """
+        self._loading_notification.pop()
+
+    @log
+    def push_loading(self):
+        """Increase loading notification counter.
+
+        If no notification is visible, start loading notification.
+        """
+        self._loading_notification.push()
+
+    @log
+    def add_notification(self, notification):
+        """Display a new notification
+
+        :param notification: notification to display
+        """
+        self._grid.add(notification)
+        self.show()
+        self.set_reveal_child(True)
+
+    @log
+    def remove_notification(self, notification, signal):
+        """Remove notification and emit a signal.
+
+        :param notification: notification to remove
+        :param signal: signal to emit: deletion or undo action
+        """
+        self._set_visibility(notification, True)
+        notification.emit(signal)
+
+
+class LoadingNotification(Gtk.Grid):
+    """LoadingNotification displays a loading notification message
+
+    It can be triggered by different all main views. Message is
+    displayed as long as at least one loading operation is in progress.
+    """
+
+    __gsignals__ = {
+        'visible': (GObject.SignalFlags.RUN_FIRST, None, ()),
+        'invisible': (GObject.SignalFlags.RUN_FIRST, None, ())
+    }
+
+    def __repr__(self):
+        return '<LoadingNotification>'
+
+    @log
+    def __init__(self):
+        super().__init__(column_spacing=18)
+        self._counter = 0
+        self._timeout_id = 0
+
+        spinner = Gtk.Spinner()
+        spinner.start()
+        self.add(spinner)
+
+        label = Gtk.Label(
+            label=_("Loading"), halign=Gtk.Align.START, hexpand=True)
+        self.add(label)
+        self.show_all()
+
+    @log
+    def pop(self):
+        """Decrease the counter. Hide notification if it reaches 0."""
+        self._counter = self._counter - 1
+
+        if self._counter == 0:
+            # Stop the timeout if necessary
+            if self._timeout_id > 0:
+                GLib.source_remove(self._timeout_id)
+                self._timeout_id = 0
+            self.emit('invisible')
+
+    @log
+    def push(self):
+        """Increase the counter. Start notification if necessary."""
+        def callback():
+            self.show_all()
+            self.emit('visible')
+
+        if self._counter == 0:
+            # Only show the notification after a small delay, thus
+            # add a timeout. 500ms feels good enough.
+            self._timeout_id = GLib.timeout_add(500, callback)
+
+        self._counter = self._counter + 1
+
+
+class PlaylistNotification(Gtk.Grid):
+    """Show a notification on playlist deletion.
+
+    It also provides an option to undo removal. Notification is added
+    to the NotificationsPopup.
+    """
+
+    __gsignals__ = {
+        'undo-deletion': (GObject.SignalFlags.RUN_FIRST, None, ()),
+        'finish-deletion': (GObject.SignalFlags.RUN_FIRST, None, ())
+    }
+
+    def __repr__(self):
+        return '<PlaylistNotification>'
+
+    @log
+    def __init__(self, notifications_popup, message, playlist_id):
+        super().__init__(column_spacing=18)
+        self._notifications_popup = notifications_popup
+        self.playlist_id = playlist_id
+
+        self._label = Gtk.Label(
+            label=message, halign=Gtk.Align.START, hexpand=True)
+        self.add(self._label)
+
+        undo_button = Gtk.Button.new_with_mnemonic(_("_Undo"))
+        undo_button.connect("clicked", self._undo_clicked)
+        self.add(undo_button)
+        self.show_all()
+
+        self._timeout_id = GLib.timeout_add_seconds(
+            5, self._notifications_popup.remove_notification, self,
+            'finish-deletion')
+
+        self._notifications_popup.add_notification(self)
+
+    @log
+    def _undo_clicked(self, widget_):
+        """Undo deletion and remove notification"""
+        if self._timeout_id > 0:
+            GLib.source_remove(self._timeout_id)
+            self._timeout_id = 0
+
+        self._notifications_popup.remove_notification(self, 'undo-deletion')
diff --git a/gnomemusic/widgets/playlistdialog.py b/gnomemusic/widgets/playlistdialog.py
index e5ce3b9..8300fd2 100644
--- a/gnomemusic/widgets/playlistdialog.py
+++ b/gnomemusic/widgets/playlistdialog.py
@@ -37,7 +37,7 @@ class PlaylistDialog():
         return '<PlaylistDialog>'
 
     @log
-    def __init__(self, parent, playlist_todelete):
+    def __init__(self, parent, playlists_todelete):
         self._ui = Gtk.Builder()
         self._ui.add_from_resource('/org/gnome/Music/PlaylistDialog.ui')
 
@@ -51,7 +51,7 @@ class PlaylistDialog():
         self._dialog_box.set_titlebar(self._title_bar)
         self._setup_dialog()
 
-        self._playlist_todelete = playlist_todelete
+        self._playlists_todelete_ids = playlists_todelete.keys()
 
         self._playlist = Playlists.get_default()
 
@@ -148,9 +148,8 @@ class PlaylistDialog():
         if self._playlist.is_static_playlist(item):
             return None
 
-        # Hide playlist that is going to be deleted
-        if (self._playlist_todelete is not None
-                and item.get_id() == self._playlist_todelete.get_id()):
+        # Hide playlists that are going to be deleted
+        if item.get_id() in self._playlists_todelete_ids:
             return None
 
         new_iter = self._model.insert_with_valuesv(
diff --git a/gnomemusic/window.py b/gnomemusic/window.py
index 0f2772b..cd36f09 100644
--- a/gnomemusic/window.py
+++ b/gnomemusic/window.py
@@ -46,6 +46,7 @@ from gnomemusic.views.initialstateview import InitialStateView
 from gnomemusic.views.searchview import SearchView
 from gnomemusic.views.songsview import SongsView
 from gnomemusic.views.playlistview import PlaylistView
+from gnomemusic.widgets.notificationspopup import NotificationsPopup
 from gnomemusic.widgets.playlistdialog import PlaylistDialog
 from gnomemusic.playlists import Playlists
 from gnomemusic.grilo import grilo
@@ -78,7 +79,6 @@ class Window(Gtk.ApplicationWindow):
         self.add_action(selectNone)
         self.set_size_request(200, 100)
         self.set_default_icon_name('gnome-music')
-        self._loading_counter = 0
 
         self.prev_view = None
         self.curr_view = None
@@ -97,74 +97,14 @@ class Window(Gtk.ApplicationWindow):
             self.maximize()
 
         self._setup_view()
-        self._setup_loading_notification()
-        self._setup_playlist_notification()
+        self.notifications_popup = NotificationsPopup()
+        self._overlay.add_overlay(self.notifications_popup)
 
         self.window_size_update_timeout = None
         self.connect("window-state-event", self._on_window_state_event)
         self.connect("configure-event", self._on_configure_event)
         grilo.connect('changes-pending', self._on_changes_pending)
 
-    @log
-    def _setup_loading_notification(self):
-        self._loading_notification = Gtk.Revealer(
-                       halign=Gtk.Align.CENTER, valign=Gtk.Align.START)
-        self._loading_notification.set_transition_type(
-                                 Gtk.RevealerTransitionType.SLIDE_DOWN)
-        self._overlay.add_overlay(self._loading_notification)
-
-        grid = Gtk.Grid(margin_bottom=18, margin_start=18, margin_end=18)
-        grid.set_column_spacing(18)
-        grid.get_style_context().add_class('app-notification')
-
-        spinner = Gtk.Spinner()
-        spinner.start()
-        grid.add(spinner)
-
-        label = Gtk.Label.new(_("Loading"))
-        grid.add(label)
-
-        self._loading_notification.add(grid)
-        self._loading_notification.show_all()
-
-    @log
-    def _setup_playlist_notification(self):
-        self._playlist_notification_timeout_id = 0
-        self._playlist_notification = Gtk.Revealer(halign=Gtk.Align.CENTER,
-                                                   valign=Gtk.Align.START)
-        self._playlist_notification.set_transition_type(
-                       Gtk.RevealerTransitionType.SLIDE_DOWN)
-        self._overlay.add_overlay(self._playlist_notification)
-
-        grid = Gtk.Grid(margin_bottom=18, margin_start=18, margin_end=18)
-        grid.set_column_spacing(12)
-        grid.get_style_context().add_class('app-notification')
-
-        def remove_notification_timeout(self):
-            # Remove the timeout if any
-            if self._playlist_notification_timeout_id > 0:
-                GLib.source_remove(self._playlist_notification_timeout_id)
-                self._playlist_notification_timeout_id = 0
-
-        # Undo playlist removal
-        def undo_remove_cb(button, self):
-            self._playlist_notification.set_reveal_child(False)
-            self.views[View.PLAYLIST].undo_playlist_deletion()
-
-            remove_notification_timeout(self)
-
-        # Playlist name label
-        self._playlist_notification.label = Gtk.Label()
-        grid.add(self._playlist_notification.label)
-
-        # Undo button
-        undo_button = Gtk.Button.new_with_mnemonic(_("_Undo"))
-        undo_button.connect("clicked", undo_remove_cb, self)
-        grid.add(undo_button)
-
-        self._playlist_notification.add(grid)
-        self._playlist_notification.show_all()
-
     @log
     def _on_changes_pending(self, data=None):
         # FIXME: This is not working right.
@@ -360,37 +300,6 @@ class Window(Gtk.ApplicationWindow):
             view = self._stack.get_visible_child().get_visible_child()
             view.select_none()
 
-    @log
-    def show_playlist_notification(self, message):
-        """Show a notification on playlist removal and provide an
-        option to undo for 5 seconds.
-        """
-
-        # Callback to remove playlists
-        def remove_playlist_timeout_cb(self):
-            # Remove the playlist
-            self.views[View.PLAYLIST].finish_playlist_deletion()
-
-            # Hide the notification
-            self._playlist_notification.set_reveal_child(False)
-
-            # Stop the timeout
-            self._playlist_notification_timeout_id = 0
-
-            return GLib.SOURCE_REMOVE
-
-        # If a notification is already visible, remove that playlist
-        if self._playlist_notification_timeout_id > 0:
-            GLib.source_remove(self._playlist_notification_timeout_id)
-            remove_playlist_timeout_cb(self)
-
-        self._playlist_notification.label.set_label(message)
-        self._playlist_notification.set_reveal_child(True)
-
-        timeout_id = GLib.timeout_add_seconds(
-            5, remove_playlist_timeout_cb, self)
-        self._playlist_notification_timeout_id = timeout_id
-
     @log
     def _on_key_press(self, widget, event):
         modifiers = Gtk.accelerator_get_default_mod_mask()
@@ -562,7 +471,7 @@ class Window(Gtk.ApplicationWindow):
                 return
 
             playlist_dialog = PlaylistDialog(
-                self, self.views[View.PLAYLIST].pl_todelete.get('playlist'))
+                self, self.views[View.PLAYLIST].pls_todelete)
             if playlist_dialog.run() == Gtk.ResponseType.ACCEPT:
                 playlists.add_to_playlist(
                     playlist_dialog.get_selected(), selected_songs)
@@ -570,37 +479,3 @@ class Window(Gtk.ApplicationWindow):
             playlist_dialog.destroy()
 
         self._stack.get_visible_child().get_selected_songs(callback)
-
-    @log
-    def push_loading_notification(self):
-        """ Increases the counter of loading notification triggers
-        running. If there is no notification is visible, the loading
-        notification is started.
-        """
-        def show_notification_cb(self):
-            self._loading_notification.set_reveal_child(True)
-            self._show_notification_timeout_id = 0
-            return GLib.SOURCE_REMOVE
-
-        if self._loading_counter == 0:
-            # Only show the notification after a small delay, thus
-            # add a timeout. 500ms feels good enough.
-            self._show_notification_timeout_id = GLib.timeout_add(
-                    500, show_notification_cb, self)
-
-        self._loading_counter = self._loading_counter + 1
-
-    @log
-    def pop_loading_notification(self):
-        """ Decreases the counter of loading notification triggers
-        running. If it reaches zero, the notification is withdrawn.
-        """
-        self._loading_counter = self._loading_counter - 1
-
-        if self._loading_counter == 0:
-            # Remove the previously set timeout, if any
-            if self._show_notification_timeout_id > 0:
-                GLib.source_remove(self._show_notification_timeout_id)
-                self._show_notification_timeout_id = 0
-
-            self._loading_notification.set_reveal_child(False)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]