Exemplo n.º 1
0
    def __init__(self, window, player):
        BaseView.__init__(self, 'search', None, window, Gd.MainViewType.LIST)
        self._items = {}
        self.isStarred = None
        self.iter_to_clean = None

        scale = self.get_scale_factor()
        loading_icon_surface = DefaultIcon(scale).get(DefaultIcon.Type.loading,
                                                      ArtSize.small)
        self._loading_icon = Gdk.pixbuf_get_from_surface(
            loading_icon_surface, 0, 0, loading_icon_surface.get_width(),
            loading_icon_surface.get_height())

        self._add_list_renderers()
        self.player = player
        self.head_iters = [None, None, None, None]
        self.songs_model = self.model
        self.previous_view = None
        self.connect('no-music-found', self._no_music_found_callback)

        self.albums_selected = []
        self._albums = {}
        self._albumWidget = AlbumWidget(player, self)
        self.add(self._albumWidget)

        self.artists_albums_selected = []
        self._artists = {}
        self._artistAlbumsWidget = None

        self._view.get_generic_view().set_show_expanders(False)
        self.items_selected = []
        self.items_selected_callback = None

        self.found_items_number = None
Exemplo n.º 2
0
    def __init__(self, window, player):
        super().__init__('search', None, window, Gd.MainViewType.LIST)

        scale = self.get_scale_factor()
        loading_icon_surface = DefaultIcon(scale).get(
            DefaultIcon.Type.loading, ArtSize.SMALL)
        self._loading_icon = Gdk.pixbuf_get_from_surface(
            loading_icon_surface, 0, 0, loading_icon_surface.get_width(),
            loading_icon_surface.get_height())

        self._add_list_renderers()
        self.player = player
        self._head_iters = [None, None, None, None]
        self._filter_model = None

        self.previous_view = None
        self.connect('no-music-found', self._no_music_found_callback)

        self._albums_selected = []
        self._albums = {}
        self._albums_index = 0
        self._album_widget = AlbumWidget(player, self)
        self.add(self._album_widget)

        self._artists_albums_selected = []
        self._artists_albums_index = 0
        self._artists = {}
        self._artist_albums_widget = None

        self._view.get_generic_view().set_show_expanders(False)
        self._items_selected = []
        self._items_selected_callback = None

        self._items_found = None
Exemplo n.º 3
0
    def __init__(self, window, player):
        BaseView.__init__(self, 'search', None, window, Gd.MainViewType.LIST)
        self._items = {}
        self.isStarred = None
        self.iter_to_clean = None

        scale = self.get_scale_factor()
        loading_icon_surface = DefaultIcon(scale).get(DefaultIcon.Type.loading,
                                                      ArtSize.small)
        self._loading_icon = Gdk.pixbuf_get_from_surface(
            loading_icon_surface,
            0,
            0,
            loading_icon_surface.get_width(),
            loading_icon_surface.get_height())

        self._add_list_renderers()
        self.player = player
        self.head_iters = [None, None, None, None]
        self.songs_model = self.model
        self.previous_view = None
        self.connect('no-music-found', self._no_music_found_callback)

        self.albums_selected = []
        self._albums = {}
        self._albumWidget = AlbumWidget(player, self)
        self.add(self._albumWidget)

        self.artists_albums_selected = []
        self._artists = {}
        self._artistAlbumsWidget = None

        self.view.get_generic_view().set_show_expanders(False)
        self.items_selected = []
        self.items_selected_callback = None

        self.found_items_number = None
Exemplo n.º 4
0
class BaseView(Gtk.Stack):
    nowPlayingIconName = 'media-playback-start-symbolic'
    errorIconName = 'dialog-error-symbolic'

    selection_mode = GObject.Property(type=bool, default=False)

    def __repr__(self):
        return '<BaseView>'

    @log
    def __init__(self, name, title, window, view_type, use_sidebar=False, sidebar=None):
        Gtk.Stack.__init__(self,
                           transition_type=Gtk.StackTransitionType.CROSSFADE)
        self._grid = Gtk.Grid(orientation=Gtk.Orientation.HORIZONTAL)
        self._offset = 0
        self._adjustmentValueId = 0
        self._adjustmentChangedId = 0
        self._scrollbarVisibleId = 0
        self.old_vsbl_range = None
        self.model = Gtk.ListStore(
            GObject.TYPE_STRING,
            GObject.TYPE_STRING,
            GObject.TYPE_STRING,
            GObject.TYPE_STRING,
            GdkPixbuf.Pixbuf,
            GObject.TYPE_OBJECT,
            GObject.TYPE_BOOLEAN,
            GObject.TYPE_INT,
            GObject.TYPE_STRING,
            GObject.TYPE_INT,
            GObject.TYPE_BOOLEAN,
            GObject.TYPE_INT
        )

        self._box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        # Setup the main view
        self._setup_view(view_type)

        if use_sidebar:
            self.stack = Gtk.Stack(
                transition_type=Gtk.StackTransitionType.SLIDE_RIGHT,
            )
            dummy = Gtk.Frame(visible=False)
            self.stack.add_named(dummy, 'dummy')
            if sidebar:
                self.stack.add_named(sidebar, 'sidebar')
            else:
                self.stack.add_named(self._box, 'sidebar')
            self.stack.set_visible_child_name('dummy')
            self._grid.add(self.stack)
        if not use_sidebar or sidebar:
            self._grid.add(self._box)

        self.star_handler = StarHandlerWidget(self, 9)
        self._cursor = None
        self.window = window
        self.header_bar = window.toolbar
        self.selection_toolbar = window.selection_toolbar
        self.header_bar._select_button.connect(
            'toggled', self._on_header_bar_toggled)
        self.header_bar._cancel_button.connect(
            'clicked', self._on_cancel_button_clicked)

        self.name = name
        self.title = title
        self.add(self._grid)

        self.show_all()
        self.view.hide()
        self._items = []

        scale = self.get_scale_factor()
        self.cache = AlbumArtCache(scale)
        self._loading_icon_surface = DefaultIcon(scale).get(
            DefaultIcon.Type.loading,
            ArtSize.medium)


        self._init = False
        grilo.connect('ready', self._on_grilo_ready)
        self.selection_socket = None
        self.header_bar.connect('selection-mode-changed',
                                self._on_selection_mode_changed)

        self._discovering_urls = {}
        grilo.connect('changes-pending', self._on_changes_pending)

    @log
    def _on_changes_pending(self, data=None):
        pass

    @log
    def _setup_view(self, view_type):
        self.view = Gd.MainView(shadow_type=Gtk.ShadowType.NONE)
        self.view.set_view_type(view_type)

        self.view.click_handler = self.view.connect('item-activated', self._on_item_activated)
        self.view.connect('selection-mode-request', self._on_selection_mode_request)

        self.view.bind_property('selection-mode', self, 'selection_mode',
                                GObject.BindingFlags.BIDIRECTIONAL)

        self.view.connect('view-selection-changed', self._on_view_selection_changed)

        self._box.pack_start(self.view, True, True, 0)

    @log
    def _on_header_bar_toggled(self, button):
        self.selection_mode = button.get_active()

        if self.selection_mode:
            self.header_bar.set_selection_mode(True)
            self.player.actionbar.set_visible(False)
            self.selection_toolbar.actionbar.set_visible(True)
            self.selection_toolbar._add_to_playlist_button.set_sensitive(False)
            self.selection_toolbar._remove_from_playlist_button.set_sensitive(False)
        else:
            self.header_bar.set_selection_mode(False)
            self.player.actionbar.set_visible(self.player.currentTrack is not None)
            self.selection_toolbar.actionbar.set_visible(False)
            self.unselect_all()

    @log
    def _on_cancel_button_clicked(self, button):
        self.view.set_selection_mode(False)
        self.header_bar.set_selection_mode(False)

    @log
    def _on_grilo_ready(self, data=None):
        # FIXME: with async changes in Window this seems never to be
        # called anymore. Fix it proper or remove.
        if (self.header_bar.get_stack().get_visible_child() == self and not self._init):
            self._populate()
        self.header_bar.get_stack().connect('notify::visible-child',
                                            self._on_headerbar_visible)

    @log
    def _on_headerbar_visible(self, widget, param):
        if self == widget.get_visible_child() and not self._init:
            self._populate()

    @log
    def _on_view_selection_changed(self, widget):
        if not self.selection_mode:
            return

        items = self.view.get_selection()
        self.update_header_from_selection(len(items))

    @log
    def update_header_from_selection(self, n_items):
        self.selection_toolbar._add_to_playlist_button.\
            set_sensitive(n_items > 0)
        self.selection_toolbar._remove_from_playlist_button.\
            set_sensitive(n_items > 0)
        if n_items > 0:
            self.header_bar._selection_menu_label.set_text(
                ngettext("Selected %d item", "Selected %d items", n_items) % n_items)
        else:
            self.header_bar._selection_menu_label.set_text(_("Click on items to select them"))

    @log
    def _populate(self, data=None):
        self._init = True
        self.populate()

    @log
    def _on_selection_mode_changed(self, widget, data=None):
        pass

    @log
    def populate(self):
        pass

    @log
    def _add_item(self, source, param, item, remaining=0, data=None):
        if not item:
            if remaining == 0:
                self.view.set_model(self.model)
                self.window.pop_loading_notification()
                self.view.show()
            return

        self._offset += 1
        artist = utils.get_artist_name(item)
        title = utils.get_media_title(item)

        _iter = self.model.append(None)

        loading_icon = Gdk.pixbuf_get_from_surface(
            self._loadin_icon_surface, 0, 0,
            self._loading_icon_surface.get_width(),
            self._loading_icon_surface.get_height())

        self.model[_iter][0, 1, 2, 3, 4, 5, 7, 9] = [
            str(item.get_id()),
            '',
            title,
            artist,
            loading_icon,
            item,
            0,
            False
        ]
        self.cache.lookup(item, self._iconWidth, self._iconHeight,
                          self._on_lookup_ready, _iter)

    @log
    def _on_lookup_ready(self, surface, _iter):
        if surface:
            pixbuf = Gdk.pixbuf_get_from_surface(surface, 0, 0,
                                                 surface.get_width(),
                                                 surface.get_height())

            self.model[_iter][4] = pixbuf

    @log
    def _add_list_renderers(self):
        pass

    @log
    def _on_item_activated(self, widget, id, path):
        pass

    @log
    def _on_selection_mode_request(self, *args):
        self.header_bar._select_button.clicked()

    @log
    def get_selected_tracks(self, callback):
        callback([])

    @log
    def _set_selection(self, value, parent=None):
        count = 0
        _iter = self.model.iter_children(parent)
        while _iter is not None:
            if self.model.iter_has_child(_iter):
                count += self._set_selection(value, _iter)
            if self.model[_iter][5]:
                self.model[_iter][6] = value
                count += 1
            _iter = self.model.iter_next(_iter)
        return count

    @log
    def select_all(self):
        """Select all the available tracks."""
        count = self._set_selection(True)

        if count > 0:
            self.selection_toolbar._add_to_playlist_button.set_sensitive(True)
            self.selection_toolbar._remove_from_playlist_button.set_sensitive(True)

        self.update_header_from_selection(count)
        self.view.queue_draw()

    @log
    def unselect_all(self):
        """Unselects all the selected tracks."""
        self._set_selection(False)
        self.selection_toolbar._add_to_playlist_button.set_sensitive(False)
        self.selection_toolbar._remove_from_playlist_button.set_sensitive(False)
        self.header_bar._selection_menu_label.set_text(_("Click on items to select them"))
        self.queue_draw()
Exemplo n.º 5
0
class BaseView(Gtk.Stack):
    nowPlayingIconName = 'media-playback-start-symbolic'
    errorIconName = 'dialog-error-symbolic'

    selection_mode = GObject.Property(type=bool, default=False)

    def __repr__(self):
        return '<BaseView>'

    @log
    def __init__(self,
                 name,
                 title,
                 window,
                 view_type,
                 use_sidebar=False,
                 sidebar=None):
        Gtk.Stack.__init__(self,
                           transition_type=Gtk.StackTransitionType.CROSSFADE)
        self._grid = Gtk.Grid(orientation=Gtk.Orientation.HORIZONTAL)
        self._offset = 0
        self._adjustmentValueId = 0
        self._adjustmentChangedId = 0
        self._scrollbarVisibleId = 0
        self.old_vsbl_range = None
        self.model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING,
                                   GObject.TYPE_STRING, GObject.TYPE_STRING,
                                   GdkPixbuf.Pixbuf, GObject.TYPE_OBJECT,
                                   GObject.TYPE_BOOLEAN, GObject.TYPE_INT,
                                   GObject.TYPE_STRING, GObject.TYPE_INT,
                                   GObject.TYPE_BOOLEAN, GObject.TYPE_INT)

        self._box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        # Setup the main view
        self._setup_view(view_type)

        if use_sidebar:
            self.stack = Gtk.Stack(
                transition_type=Gtk.StackTransitionType.SLIDE_RIGHT, )
            dummy = Gtk.Frame(visible=False)
            self.stack.add_named(dummy, 'dummy')
            if sidebar:
                self.stack.add_named(sidebar, 'sidebar')
            else:
                self.stack.add_named(self._box, 'sidebar')
            self.stack.set_visible_child_name('dummy')
            self._grid.add(self.stack)
        if not use_sidebar or sidebar:
            self._grid.add(self._box)

        self.star_handler = StarHandlerWidget(self, 9)
        self._cursor = None
        self.window = window
        self.header_bar = window.toolbar
        self.selection_toolbar = window.selection_toolbar
        self.header_bar._select_button.connect('toggled',
                                               self._on_header_bar_toggled)
        self.header_bar._cancel_button.connect('clicked',
                                               self._on_cancel_button_clicked)

        self.name = name
        self.title = title
        self.add(self._grid)

        self.show_all()
        self.view.hide()
        self._items = []

        scale = self.get_scale_factor()
        self.cache = AlbumArtCache(scale)
        self._loading_icon_surface = DefaultIcon(scale).get(
            DefaultIcon.Type.loading, ArtSize.medium)

        self._init = False
        grilo.connect('ready', self._on_grilo_ready)
        self.selection_socket = None
        self.header_bar.connect('selection-mode-changed',
                                self._on_selection_mode_changed)

        self._discovering_urls = {}
        grilo.connect('changes-pending', self._on_changes_pending)

    @log
    def _on_changes_pending(self, data=None):
        pass

    @log
    def _setup_view(self, view_type):
        self.view = Gd.MainView(shadow_type=Gtk.ShadowType.NONE)
        self.view.set_view_type(view_type)

        self.view.click_handler = self.view.connect('item-activated',
                                                    self._on_item_activated)
        self.view.connect('selection-mode-request',
                          self._on_selection_mode_request)

        self.view.bind_property('selection-mode', self, 'selection_mode',
                                GObject.BindingFlags.BIDIRECTIONAL)

        self.view.connect('view-selection-changed',
                          self._on_view_selection_changed)

        self._box.pack_start(self.view, True, True, 0)

    @log
    def _on_header_bar_toggled(self, button):
        self.selection_mode = button.get_active()

        if self.selection_mode:
            self.header_bar.set_selection_mode(True)
            self.player.actionbar.set_visible(False)
            self.selection_toolbar.actionbar.set_visible(True)
            self.selection_toolbar._add_to_playlist_button.set_sensitive(False)
            self.selection_toolbar._remove_from_playlist_button.set_sensitive(
                False)
        else:
            self.header_bar.set_selection_mode(False)
            self.player.actionbar.set_visible(
                self.player.currentTrack is not None)
            self.selection_toolbar.actionbar.set_visible(False)
            self.unselect_all()

    @log
    def _on_cancel_button_clicked(self, button):
        self.view.set_selection_mode(False)
        self.header_bar.set_selection_mode(False)

    @log
    def _on_grilo_ready(self, data=None):
        if (self.header_bar.get_stack().get_visible_child() == self
                and not self._init):
            self._populate()
        self.header_bar.get_stack().connect('notify::visible-child',
                                            self._on_headerbar_visible)

    @log
    def _on_headerbar_visible(self, widget, param):
        if self == widget.get_visible_child() and not self._init:
            self._populate()

    @log
    def _on_view_selection_changed(self, widget):
        if not self.selection_mode:
            return

        items = self.view.get_selection()
        self.update_header_from_selection(len(items))

    @log
    def update_header_from_selection(self, n_items):
        self.selection_toolbar._add_to_playlist_button.\
            set_sensitive(n_items > 0)
        self.selection_toolbar._remove_from_playlist_button.\
            set_sensitive(n_items > 0)
        if n_items > 0:
            self.header_bar._selection_menu_label.set_text(
                ngettext("Selected %d item", "Selected %d items", n_items) %
                n_items)
        else:
            self.header_bar._selection_menu_label.set_text(
                _("Click on items to select them"))

    @log
    def _populate(self, data=None):
        self._init = True
        self.populate()

    @log
    def _on_selection_mode_changed(self, widget, data=None):
        pass

    @log
    def populate(self):
        print('populate')

    @log
    def _add_item(self, source, param, item, remaining=0, data=None):
        self.window.notification.set_timeout(0)
        if not item:
            if remaining == 0:
                self.view.set_model(self.model)
                self.window.notification.dismiss()
                self.view.show()
            return

        self._offset += 1
        artist = utils.get_artist_name(item)
        title = utils.get_media_title(item)

        _iter = self.model.append(None)

        loading_icon = Gdk.pixbuf_get_from_surface(
            self._loadin_icon_surface, 0, 0,
            self._loading_icon_surface.get_width(),
            self._loading_icon_surface.get_height())

        self.model[_iter][0, 1, 2, 3, 4, 5, 7, 9] = [
            str(item.get_id()), '', title, artist, loading_icon, item, 0, False
        ]
        self.cache.lookup(item, self._iconWidth, self._iconHeight,
                          self._on_lookup_ready, _iter)

    @log
    def _on_lookup_ready(self, surface, _iter):
        if surface:
            pixbuf = Gdk.pixbuf_get_from_surface(surface, 0, 0,
                                                 surface.get_width(),
                                                 surface.get_height())

            self.model[_iter][4] = pixbuf

    @log
    def _add_list_renderers(self):
        pass

    @log
    def _on_item_activated(self, widget, id, path):
        pass

    @log
    def _on_selection_mode_request(self, *args):
        self.header_bar._select_button.clicked()

    @log
    def get_selected_tracks(self, callback):
        callback([])

    def _on_list_widget_star_render(self, col, cell, model, _iter, data):
        pass

    @log
    def _set_selection(self, value, parent=None):
        count = 0
        _iter = self.model.iter_children(parent)
        while _iter is not None:
            if self.model.iter_has_child(_iter):
                count += self._set_selection(value, _iter)
            if self.model[_iter][5]:
                self.model[_iter][6] = value
                count += 1
            _iter = self.model.iter_next(_iter)
        return count

    @log
    def select_all(self):
        """Select all the available tracks."""
        count = self._set_selection(True)

        if count > 0:
            self.selection_toolbar._add_to_playlist_button.set_sensitive(True)
            self.selection_toolbar._remove_from_playlist_button.set_sensitive(
                True)

        self.update_header_from_selection(count)
        self.view.queue_draw()

    @log
    def unselect_all(self):
        """Unselects all the selected tracks."""
        self._set_selection(False)
        self.selection_toolbar._add_to_playlist_button.set_sensitive(False)
        self.selection_toolbar._remove_from_playlist_button.set_sensitive(
            False)
        self.header_bar._selection_menu_label.set_text(
            _("Click on items to select them"))
        self.queue_draw()
Exemplo n.º 6
0
class BaseView(Gtk.Stack):
    """Base Class for all view classes"""

    _now_playing_icon_name = 'media-playback-start-symbolic'
    _error_icon_name = 'dialog-error-symbolic'
    selection_mode = GObject.Property(type=bool, default=False)

    def __repr__(self):
        return '<BaseView>'

    @log
    def __init__(self,
                 name,
                 title,
                 window,
                 view_type,
                 use_sidebar=False,
                 sidebar=None):
        """Initialize
        :param name: The view name
        :param title: The view title
        :param GtkWidget window: The main window
        :param view_type: The Gtk view type
        :param use_sidebar: Whether to use sidebar
        :param sidebar: The sidebar object (Default: Gtk.Box)
        """

        Gtk.Stack.__init__(self,
                           transition_type=Gtk.StackTransitionType.CROSSFADE)
        self._grid = Gtk.Grid(orientation=Gtk.Orientation.HORIZONTAL)
        self._offset = 0
        self.model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING,
                                   GObject.TYPE_STRING, GObject.TYPE_STRING,
                                   GdkPixbuf.Pixbuf, GObject.TYPE_OBJECT,
                                   GObject.TYPE_BOOLEAN, GObject.TYPE_INT,
                                   GObject.TYPE_STRING, GObject.TYPE_INT,
                                   GObject.TYPE_BOOLEAN, GObject.TYPE_INT)
        self._box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        # Setup the main view
        self._setup_view(view_type)

        if use_sidebar:
            self.stack = Gtk.Stack(
                transition_type=Gtk.StackTransitionType.SLIDE_RIGHT, )
            dummy = Gtk.Frame(visible=False)
            self.stack.add_named(dummy, 'dummy')
            if sidebar:
                self.stack.add_named(sidebar, 'sidebar')
            else:
                self.stack.add_named(self._box, 'sidebar')
            self.stack.set_visible_child_name('dummy')
            self._grid.add(self.stack)
        if not use_sidebar or sidebar:
            self._grid.add(self._box)

        self._star_handler = StarHandlerWidget(self, 9)
        self._window = window
        self._header_bar = window.toolbar
        self._selection_toolbar = window.selection_toolbar
        self._header_bar._select_button.connect('toggled',
                                                self._on_header_bar_toggled)
        self._header_bar._cancel_button.connect('clicked',
                                                self._on_cancel_button_clicked)

        self.name = name
        self.title = title

        self.add(self._grid)
        self.show_all()
        self._view.hide()

        scale = self.get_scale_factor()
        self._cache = AlbumArtCache(scale)
        self._loading_icon_surface = DefaultIcon(scale).get(
            DefaultIcon.Type.loading, ArtSize.medium)

        self._init = False
        grilo.connect('ready', self._on_grilo_ready)
        self._header_bar.connect('selection-mode-changed',
                                 self._on_selection_mode_changed)
        grilo.connect('changes-pending', self._on_changes_pending)

    @log
    def _on_changes_pending(self, data=None):
        pass

    @log
    def _setup_view(self, view_type):
        """Instantiate and set up the view object"""
        self._view = Gd.MainView(shadow_type=Gtk.ShadowType.NONE)
        self._view.set_view_type(view_type)

        self._view.click_handler = self._view.connect('item-activated',
                                                      self._on_item_activated)
        self._view.connect('selection-mode-request',
                           self._on_selection_mode_request)

        self._view.bind_property('selection-mode', self, 'selection_mode',
                                 GObject.BindingFlags.BIDIRECTIONAL)

        self._view.connect('view-selection-changed',
                           self._on_view_selection_changed)

        self._box.pack_start(self._view, True, True, 0)

    @log
    def _on_header_bar_toggled(self, button):
        self.selection_mode = button.get_active()

        if self.selection_mode:
            self._header_bar.set_selection_mode(True)
            self.player.actionbar.set_visible(False)
            select_toolbar = self._selection_toolbar
            select_toolbar.actionbar.set_visible(True)
            select_toolbar._add_to_playlist_button.set_sensitive(False)
            select_toolbar._remove_from_playlist_button.set_sensitive(False)
        else:
            self._header_bar.set_selection_mode(False)
            track_playing = self.player.currentTrack is not None
            self.player.actionbar.set_visible(track_playing)
            self._selection_toolbar.actionbar.set_visible(False)
            self.unselect_all()

    @log
    def _on_cancel_button_clicked(self, button):
        self._view.set_selection_mode(False)
        self._header_bar.set_selection_mode(False)

    @log
    def _on_grilo_ready(self, data=None):
        if (self._header_bar.get_stack().get_visible_child() == self
                and not self._init):
            self._populate()
        self._header_bar.get_stack().connect('notify::visible-child',
                                             self._on_headerbar_visible)

    @log
    def _on_headerbar_visible(self, widget, param):
        if (self == widget.get_visible_child() and not self._init):
            self._populate()

    @log
    def _on_view_selection_changed(self, widget):
        if not self.selection_mode:
            return
        items = self._view.get_selection()
        self.update_header_from_selection(len(items))

    @log
    def update_header_from_selection(self, n_items):
        """Updates header during item selection."""
        select_toolbar = self._selection_toolbar
        select_toolbar._add_to_playlist_button.set_sensitive(n_items > 0)
        select_toolbar._remove_from_playlist_button.set_sensitive(n_items > 0)
        if n_items > 0:
            self._header_bar._selection_menu_label.set_text(
                ngettext("Selected {} item", "Selected {} items",
                         n_items).format(n_items))
        else:
            self._header_bar._selection_menu_label.set_text(
                _("Click on items to select them"))

    @log
    def _populate(self, data=None):
        self._init = True
        self.populate()

    @log
    def _on_selection_mode_changed(self, widget, data=None):
        pass

    @log
    def populate(self):
        pass

    @log
    def _add_item(self, source, param, item, remaining=0, data=None):
        if not item:
            if remaining == 0:
                self._view.set_model(self.model)
                self._window.pop_loading_notification()
                self._view.show()
            return
        self._offset += 1
        artist = utils.get_artist_name(item)
        title = utils.get_media_title(item)

        itr = self.model.append(None)
        loading_icon = Gdk.pixbuf_get_from_surface(
            self._loadin_icon_surface, 0, 0,
            self._loading_icon_surface.get_width(),
            self._loading_icon_surface.get_height())

        self.model[itr][0, 1, 2, 3, 4, 5, 7, 9] = [
            str(item.get_id()), '', title, artist, loading_icon, item, 0, False
        ]

    @log
    def _on_lookup_ready(self, surface, itr):
        if surface:
            pixbuf = Gdk.pixbuf_get_from_surface(surface, 0, 0,
                                                 surface.get_width(),
                                                 surface.get_height())
            self.model[itr][4] = pixbuf

    @log
    def _add_list_renderers(self):
        pass

    @log
    def _on_item_activated(self, widget, id, path):
        pass

    @log
    def _on_selection_mode_request(self, *args):
        self._header_bar._select_button.clicked()

    @log
    def get_selected_songs(self, callback):
        callback([])

    @log
    def _set_selection(self, value, parent=None):
        count = 0
        itr = self.model.iter_children(parent)
        while itr != None:
            if self.model.iter_has_child(itr):
                count += self._set_selection(value, itr)
            if self.model[itr][5] != None:
                self.model[itr][6] = value
                count += 1
            itr = self.model.iter_next(itr)
        return count

    @log
    def select_all(self):
        """Select all the available songs."""
        count = self._set_selection(True)

        if count > 0:
            select_toolbar = self._selection_toolbar
            select_toolbar._add_to_playlist_button.set_sensitive(True)
            select_toolbar._remove_from_playlist_button.set_sensitive(True)

        self.update_header_from_selection(count)
        self._view.queue_draw()

    @log
    def unselect_all(self):
        """Unselects all the selected songs."""
        self._set_selection(False)
        select_toolbar = self._selection_toolbar
        select_toolbar._add_to_playlist_button.set_sensitive(False)
        select_toolbar._remove_from_playlist_button.set_sensitive(False)
        self._header_bar._selection_menu_label.set_text(
            _("Click on items to select them"))
        self.queue_draw()