Пример #1
0
 def __browser_cb(self, browser, songs, sorted):
     if browser.background:
         bg = background_filter()
         if bg:
             songs = list(filter(bg, songs))
     print_d(f"Setting {len(songs)} songs...")
     self.songlist.set_songs(songs, sorted)
Пример #2
0
    def __update_filter(self, entry, text):
        self.__filter = None
        if not Query.match_all(text):
            tags = self.__model.tags + ["album"]
            self.__filter = Query(text, star=tags).search
        self.__bg_filter = background_filter()

        self.view.get_model().refilter()
Пример #3
0
    def __update_filter(self, entry, text):
        self.__filter = None
        query = self.__search.query
        if not query.matches_all:
            self.__filter = query.search
        self.__bg_filter = background_filter()

        self.view.get_model().refilter()
Пример #4
0
    def __update_filter(self, entry, text):
        self.__filter = None
        star = self.__model.tags + ["album"]
        query = self.__search.get_query(star)
        if not query.matches_all:
            self.__filter = query.search
        self.__bg_filter = background_filter()

        self.view.get_model().refilter()
Пример #5
0
    def __update_filter(self, entry, text):
        self.__filter = None
        star = self.__model.tags + ["album"]
        query = self.__search.get_query(star)
        if not query.matches_all:
            self.__filter = query.search
        self.__bg_filter = background_filter()

        self.view.get_model().refilter()
Пример #6
0
 def activate(self):
     if self._text is not None and Query.is_parsable(self._text):
         star = dict.fromkeys(SongList.star)
         star.update(self.__star)
         self._filter = Query(self._text, star.keys()).search
         songs = filter(self._filter, self._library)
         bg = background_filter()
         if bg:
             songs = filter(bg, songs)
         self.__panes[0].fill(songs)
Пример #7
0
 def list(self, tag):
     library = quodlibet.library.library
     bg = background_filter()
     if bg:
         songs = filter(bg, library.itervalues())
         tags = set()
         for song in songs:
             tags.update(song.list(tag))
         return list(tags)
     return library.tag_values(tag)
Пример #8
0
 def list(self, tag):
     """Return a list of unique values for the given tag. This needs to be
     here since not all browsers pull from the default library.
     """
     library = app.library
     bg = background_filter()
     if bg:
         songs = filter(bg, library.values())
         return list({value for song in songs for value in song.list(tag)})
     return list(library.tag_values(tag))
Пример #9
0
 def list(self, tag):
     """Return a list of unique values for the given tag. This needs to be
     here since not all browsers pull from the default library.
     """
     library = app.library
     bg = background_filter()
     if bg:
         songs = filter(bg, itervalues(library))
         return list({value for song in songs for value in song.list(tag)})
     return list(library.tag_values(tag))
Пример #10
0
 def list(self, tag):
     library = app.library
     bg = background_filter()
     if bg:
         songs = filter(bg, library.itervalues())
         tags = set()
         for song in songs:
             tags.update(song.list(tag))
         return list(tags)
     return library.tag_values(tag)
Пример #11
0
 def activate(self):
     text = self._get_text()
     if Query.is_parsable(text):
         star = dict.fromkeys(SongList.star)
         star.update(self.__star)
         self._filter = Query(text, star.keys()).search
         songs = filter(self._filter, self._library)
         bg = background_filter()
         if bg:
             songs = filter(bg, songs)
         self._panes[0].fill(songs)
Пример #12
0
 def activate(self):
     star = dict.fromkeys(SongList.star)
     star.update(self.__star)
     query = self._sb_box.get_query(star.keys())
     if query.is_parsable:
         self._filter = query.search
         songs = list(filter(self._filter, self._library))
         bg = background_filter()
         if bg:
             songs = list(filter(bg, songs))
         self._panes[0].fill(songs)
Пример #13
0
 def activate(self):
     star = dict.fromkeys(SongList.star)
     star.update(self.__star)
     query = self._sb_box.get_query(star.keys())
     if query.is_parsable:
         self._filter = query.search
         songs = list(filter(self._filter, self._library))
         bg = background_filter()
         if bg:
             songs = list(filter(bg, songs))
         self._panes[0].fill(songs)
Пример #14
0
 def activate(self):
     star = dict.fromkeys(SongList.star)
     star.update(self.__star)
     # TODO: get query from SearchBarBox (but with dynamic star)
     query = Query(self._get_text(), star.keys())
     if query.is_parsable:
         self._filter = query.search
         songs = filter(self._filter, self._library)
         bg = background_filter()
         if bg:
             songs = filter(bg, songs)
         self._panes[0].fill(songs)
Пример #15
0
 def list(self, tag):
     """Return a list of unique values for the given tag. This needs to be
     here since not all browsers pull from the default library.
     """
     library = app.library
     bg = background_filter()
     if bg:
         songs = filter(bg, library.itervalues())
         tags = set()
         for song in songs:
             tags.update(song.list(tag))
         return list(tags)
     return library.tag_values(tag)
Пример #16
0
    def __filter_menu_actions(self, menuitem):
        name = menuitem.get_name()

        if name == "PlayedRecently":
            self.__make_query("#(lastplayed < 7 days ago)")
        elif name == "AddedRecently":
            self.__make_query("#(added < 7 days ago)")
        elif name == "TopRated":
            bg = background_filter()
            songs = (bg and filter(bg, self.__library)) or self.__library
            songs = [song.get("~#playcount", 0) for song in songs]
            if len(songs) == 0:
                return
            songs.sort()
            if len(songs) < 40:
                self.__make_query("#(playcount > %d)" % (songs[0] - 1))
            else:
                self.__make_query("#(playcount > %d)" % (songs[-40] - 1))
Пример #17
0
    def __update_filter(self, entry, text, scroll_up=True, restore=False):
        model = self.view.get_model()

        self.__filter = None
        if not Query.match_all(text):
            self.__filter = Query(text, star=["~people", "album"]).search
        self.__bg_filter = background_filter()

        self.__inhibit()

        # If we're hiding "All Albums", then there will always
        # be something to filter ­— probably there's a better
        # way to implement this

        if (not restore or self.__filter or self.__bg_filter) or (not
            config.getboolean("browsers", "covergrid_all", False)):
            model.refilter()

        self.__uninhibit()
Пример #18
0
    def __update_filter(self, entry, text, scroll_up=True, restore=False):
        model = self.view.get_model()

        self.__filter = None
        if not Query.match_all(text):
            self.__filter = Query(text, star=["~people", "album"]).search
        self.__bg_filter = background_filter()

        self.__inhibit()

        # If we're hiding "All Albums", then there will always
        # be something to filter ­— probably there's a better
        # way to implement this

        if (not restore or self.__filter or self.__bg_filter) or (not
            config.getboolean("browsers", "covergrid_all", False)):
            model.refilter()

        self.__uninhibit()
Пример #19
0
    def __browser_cb(self, browser, songs, sorted, library, player):
        if browser.background:
            bg = background_filter()
            if bg:
                songs = filter(bg, songs)
        self.songlist.set_songs(songs, sorted)

        # After the first time the browser activates, which should always
        # happen if we start up and restore, restore the playing song.
        # Because the browser has send us songs we can be sure it has
        # registered all its libraries.
        if self.__first_browser_set:
            self.__first_browser_set = False

            song = library.librarian.get(config.get("memory", "song"))
            seek_pos = config.getint("memory", "seek", 0)
            config.set("memory", "seek", 0)
            if song is not None:
                player.setup(self.playlist, song, seek_pos)
Пример #20
0
    def __filter_menu_actions(self, menuitem):
        name = menuitem.get_name()

        if name == "PlayedRecently":
            self._make_query("#(lastplayed < 7 days ago)")
        elif name == "AddedRecently":
            self._make_query("#(added < 7 days ago)")
        elif name == "TopRated":
            bg = background_filter()
            songs = (bg and filter(bg, self._library)) or self._library
            songs = [song.get("~#playcount", 0) for song in songs]
            if len(songs) == 0:
                return
            songs.sort()
            if len(songs) < 40:
                self._make_query("#(playcount > %d)" % (songs[0] - 1))
            else:
                self._make_query("#(playcount > %d)" % (songs[-40] - 1))
        elif name == "All":
            self._browser.unfilter()
Пример #21
0
    def __update_filter(self, entry=None, text=None, scroll_up=True,
                        restore=False):
        model = self.view.get_model()

        self.__filter = None
        query = self.__search.get_query(self.STAR)
        if not query.matches_all:
            self.__filter = query.search
        self.__bg_filter = background_filter()

        self.__inhibit()

        # If we're hiding "All Albums", then there will always
        # be something to filter ­— probably there's a better
        # way to implement this

        if (not restore or self.__filter or self.__bg_filter) or (not
            config.getboolean("browsers", "covergrid_all", True)):
            model.refilter()

        self.__uninhibit()
Пример #22
0
    def __update_filter(self, entry, text, scroll_up=True, restore=False):
        model = self.view.get_model()

        self.__filter = None
        if not Query.match_all(text):
            self.__filter = Query(text, star=["~people", "album"]).search
        self.__bg_filter = background_filter()

        self.__inhibit()

        # We could be smart and try to scroll to a selected album
        # but that introduces lots of wild scrolling. Feel free to change it.
        # Without scrolling the TV tries to stay at the same position
        # (40% down) which makes no sense, so always go to the top.
        if scroll_up:
            self.view.scroll_to_point(0, 0)

        # Don't filter on restore if there is nothing to filter
        if not restore or self.__filter or self.__bg_filter:
            model.refilter()

        self.__uninhibit()
Пример #23
0
    def __update_filter(self, entry, text, scroll_up=True, restore=False):
        model = self.view.get_model()

        self.__filter = None
        if not Query.match_all(text):
            self.__filter = Query(text, star=["~people", "album"]).search
        self.__bg_filter = background_filter()

        self.__inhibit()

        # We could be smart and try to scroll to a selected album
        # but that introduces lots of wild scrolling. Feel free to change it.
        # Without scrolling the TV tries to stay at the same position
        # (40% down) which makes no sense, so always go to the top.
        if scroll_up:
            self.view.scroll_to_point(0, 0)

        # Don't filter on restore if there is nothing to filter
        if not restore or self.__filter or self.__bg_filter:
            model.refilter()

        self.__uninhibit()
Пример #24
0
    def __browser_cb(self, browser, songs, sorted, library, player):
        if browser.background:
            bg = background_filter()
            if bg:
                songs = filter(bg, songs)
        self.songlist.set_songs(songs, sorted)

        # After the first time the browser activates, which should always
        # happen if we start up and restore, restore the playing song.
        # Because the browser has send us songs we can be sure it has
        # registered all its libraries.
        if self.__first_browser_set:
            self.__first_browser_set = False

            song = library.librarian.get(config.get("memory", "song"))
            seek_pos = config.getfloat("memory", "seek", 0)
            config.set("memory", "seek", 0)
            if song is not None:
                player.setup(self.playlist, song, seek_pos)

            if self.__restore_cb:
                self.__restore_cb()
                self.__restore_cb = None
Пример #25
0
    def __init__(self, library):
        super(CollectionBrowser, self).__init__(spacing=6)
        self.set_orientation(Gtk.Orientation.VERTICAL)

        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        sw = ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        self.view = view = CollectionView()
        view.set_headers_visible(False)
        model_sort = CollectionSortModel(model=self.__model)
        model_filter = CollectionFilterModel(child_model=model_sort)
        self.__filter = None
        self.__bg_filter = background_filter()
        model_filter.set_visible_func(self.__parse_query)
        view.set_model(model_filter)

        def cmpa(a, b):
            """Like cmp but treats values that evaluate to false as inf"""
            if not a and b:
                return 1
            if not b and a:
                return -1
            return cmp(a, b)

        def cmp_rows(model, i1, i2, data):
            t1, t2 = model[i1][0], model[i2][0]
            pos1 = _ORDERING.get(t1, 0)
            pos2 = _ORDERING.get(t2, 0)
            if pos1 or pos2:
                return cmp(pos1, pos2)

            if not isinstance(t1, AlbumNode):
                return cmp(util.human_sort_key(t1), util.human_sort_key(t2))

            a1, a2 = t1.album, t2.album
            return (cmpa(a1.peoplesort, a2.peoplesort) or
                    cmpa(a1.date, a2.date) or
                    cmpa(a1.sort, a2.sort) or
                    cmp(a1.key, a2.key))

        model_sort.set_sort_func(0, cmp_rows)
        model_sort.set_sort_column_id(0, Gtk.SortType.ASCENDING)

        column = Gtk.TreeViewColumn("albums")

        def cell_data(column, cell, model, iter_, data):
            markup = model.get_markup(self.__model.tags, iter_)
            cell.markup = markup
            cell.set_property('markup', markup)

        def get_scaled_cover(item):
            if item.scanned:
                return item.cover

            scale_factor = self.get_scale_factor()
            item.scan_cover(scale_factor=scale_factor)
            return item.cover

        def cell_data_pb(column, cell, model, iter_, data):
            album = model.get_album(iter_)
            if album is None:
                cell.set_property('icon-name', Icons.FOLDER)
            else:
                item = model.get_value(iter_)
                cover = get_scaled_cover(item)
                if cover:
                    cover = add_border_widget(cover, view)
                    surface = get_surface_for_pixbuf(self, cover)
                    cell.set_property("surface", surface)
                else:
                    cell.set_property('icon-name', Icons.MEDIA_OPTICAL)

        imgrender = Gtk.CellRendererPixbuf()
        render = Gtk.CellRendererText()
        if view.supports_hints():
            render.set_property('ellipsize', Pango.EllipsizeMode.END)
        column.pack_start(imgrender, False)
        column.pack_start(render, True)
        column.set_cell_data_func(render, cell_data)
        column.set_cell_data_func(imgrender, cell_data_pb)
        view.append_column(column)

        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.add(view)

        hbox = Gtk.HBox(spacing=6)

        prefs = Gtk.Button()
        prefs.add(SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU))
        prefs.connect('clicked', lambda *x: Preferences(self))

        self.accelerators = Gtk.AccelGroup()
        search = SearchBarBox(completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)
        search.connect('query-changed', self.__update_filter)
        connect_obj(search, 'focus-out', lambda w: w.grab_focus(), view)
        self.__search = search

        hbox.pack_start(search, True, True, 0)
        hbox.pack_start(prefs, False, True, 0)

        self.pack_start(Align(hbox, left=6, top=6), False, True, 0)
        self.pack_start(sw, True, True, 0)

        view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.__sig = view.get_selection().connect('changed',
            self.__selection_changed)
        view.connect('row-activated', self.__play)
        connect_obj(view, 'popup-menu', self.__popup, view, library)

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        view.drag_source_set(
            Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY)
        view.connect("drag-data-get", self.__drag_data_get)

        self.connect("destroy", self.__destroy)

        self.show_all()
Пример #26
0
    def __init__(self, library):
        super(AlbumList, self).__init__(spacing=6)
        self.set_orientation(Gtk.Orientation.VERTICAL)

        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        self._cover_cancel = Gio.Cancellable()

        sw = ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        self.view = view = AllTreeView()
        view.set_headers_visible(False)
        model_sort = AlbumSortModel(model=self.__model)
        model_filter = AlbumFilterModel(child_model=model_sort)

        self.__bg_filter = background_filter()
        self.__filter = None
        model_filter.set_visible_func(self.__parse_query)

        render = Gtk.CellRendererPixbuf()
        self.__cover_column = column = Gtk.TreeViewColumn("covers", render)
        column.set_visible(config.getboolean("browsers", "album_covers"))
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        column.set_fixed_width(get_cover_size() + 12)
        render.set_property('height', get_cover_size() + 8)
        render.set_property('width', get_cover_size() + 8)

        def cell_data_pb(column, cell, model, iter_, no_cover):
            item = model.get_value(iter_)

            if item.album is None:
                surface = None
            elif item.cover:
                pixbuf = item.cover
                pixbuf = add_border_widget(pixbuf, self.view)
                surface = get_surface_for_pixbuf(self, pixbuf)
                # don't cache, too much state has an effect on the result
                self.__last_render_surface = None
            else:
                surface = no_cover

            if self.__last_render_surface == surface:
                return
            self.__last_render_surface = surface
            cell.set_property("surface", surface)

        column.set_cell_data_func(render, cell_data_pb, self._no_cover)
        view.append_column(column)

        render = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("albums", render)
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        if view.supports_hints():
            render.set_property('ellipsize', Pango.EllipsizeMode.END)

        def cell_data(column, cell, model, iter_, data):
            album = model.get_album(iter_)

            if album is None:
                text = "<b>%s</b>\n" % _("All Albums")
                text += numeric_phrase("%d album", "%d albums", len(model) - 1)
                markup = text
            else:
                markup = self.display_pattern % album

            if self.__last_render == markup:
                return
            self.__last_render = markup
            cell.markup = markup
            cell.set_property('markup', markup)

        column.set_cell_data_func(render, cell_data)
        view.append_column(column)

        view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        view.set_rules_hint(True)
        view.set_search_equal_func(self.__search_func, None)
        view.set_search_column(0)
        view.set_model(model_filter)
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.add(view)

        view.connect('row-activated', self.__play_selection)
        self.__sig = view.connect(
            'selection-changed',
            util.DeferredSignal(self.__update_songs, owner=view))

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        view.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, targets,
                             Gdk.DragAction.COPY)
        view.connect("drag-data-get", self.__drag_data_get)
        connect_obj(view, 'popup-menu', self.__popup, view, library)

        self.accelerators = Gtk.AccelGroup()
        search = SearchBarBox(completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)
        search.connect('query-changed', self.__update_filter)
        connect_obj(search, 'focus-out', lambda w: w.grab_focus(), view)
        self.__search = search

        prefs = PreferencesButton(self, model_sort)
        search.pack_start(prefs, False, True, 0)
        self.pack_start(Align(search, left=6, top=6), False, True, 0)
        self.pack_start(sw, True, True, 0)

        self.connect("destroy", self.__destroy)

        self.enable_row_update(view, sw, self.__cover_column)

        self.connect('key-press-event', self.__key_pressed, library.librarian)

        if app.cover_manager:
            connect_destroy(app.cover_manager, "cover-changed",
                            self._cover_changed)

        self.show_all()
Пример #27
0
    def __init__(self, library):
        super(CollectionBrowser, self).__init__(spacing=6)
        self.set_orientation(Gtk.Orientation.VERTICAL)

        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        sw = ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        self.view = view = CollectionView()
        view.set_headers_visible(False)
        model_sort = CollectionSortModel(model=self.__model)
        model_filter = CollectionFilterModel(child_model=model_sort)
        self.__filter = None
        self.__bg_filter = background_filter()
        model_filter.set_visible_func(self.__parse_query)
        view.set_model(model_filter)

        def sort(model, i1, i2, data):
            t1, t2 = model[i1][0], model[i2][0]
            if t1 is None or t2 is None:
                # FIXME: why?
                return 0

            # FIXME: order this deterministically
            if t1 is MultiNode or t1 is UnknownNode or \
                    t2 is MultiNode or t2 is UnknownNode:
                return -cmp(t1, t2)

            if not isinstance(t1, Album):
                return cmp(util.human_sort_key(t1), util.human_sort_key(t2))

            a1, a2 = t1, t2
            return (cmp(a1.peoplesort and a1.peoplesort[0],
                        a2.peoplesort and a2.peoplesort[0]) or
                        cmp(a1.date or "ZZZZ", a2.date or "ZZZZ") or
                        cmp((a1.sort, a1.key), (a2.sort, a2.key)))

        model_sort.set_sort_func(0, sort)
        model_sort.set_sort_column_id(0, Gtk.SortType.ASCENDING)

        column = Gtk.TreeViewColumn("albums")

        def cell_data(column, cell, model, iter_, data):
            markup = model.get_markup(self.__model.tags, iter_)
            cell.markup = markup
            cell.set_property('markup', markup)

        def get_scaled_cover(album):
            # XXX: Cache this somewhere else
            cover = None
            if not hasattr(album, "_scaled_cover"):
                scale_factor = self.get_scale_factor()
                album.scan_cover(scale_factor=scale_factor)
                if album.cover:
                    s = 25 * scale_factor
                    cover = scale(album.cover, (s, s))
                    album._scaled_cover = cover
            else:
                cover = album._scaled_cover
            return cover

        def cell_data_pb(column, cell, model, iter_, data):
            album = model.get_album(iter_)
            if album is None:
                cell.set_property('icon-name', Icons.FOLDER)
            else:
                cover = get_scaled_cover(album)
                if cover:
                    cover = add_border_widget(cover, view)
                    surface = get_surface_for_pixbuf(self, cover)
                    cell.set_property("surface", surface)
                else:
                    cell.set_property('icon-name', Icons.MEDIA_OPTICAL)

        imgrender = Gtk.CellRendererPixbuf()
        render = Gtk.CellRendererText()
        if view.supports_hints():
            render.set_property('ellipsize', Pango.EllipsizeMode.END)
        column.pack_start(imgrender, False)
        column.pack_start(render, True)
        column.set_cell_data_func(render, cell_data)
        column.set_cell_data_func(imgrender, cell_data_pb)
        view.append_column(column)

        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.add(view)

        hbox = Gtk.HBox(spacing=6)

        prefs = Gtk.Button()
        prefs.add(SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU))
        prefs.connect('clicked', lambda *x: Preferences(self))

        search = SearchBarBox(completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)

        search.connect('query-changed', self.__update_filter)
        self.__search = search

        hbox.pack_start(search, True, True, 0)
        hbox.pack_start(prefs, False, True, 0)

        self.pack_start(Align(hbox, left=6, top=6), False, True, 0)
        self.pack_start(sw, True, True, 0)

        view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.__sig = view.get_selection().connect('changed',
            self.__selection_changed)
        view.connect('row-activated', self.__play)
        connect_obj(view, 'popup-menu', self.__popup, view, library)

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        view.drag_source_set(
            Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY)
        view.connect("drag-data-get", self.__drag_data_get)

        self.connect("destroy", self.__destroy)

        self.show_all()
Пример #28
0
    def __init__(self, library, main):
        super(CollectionBrowser, self).__init__(spacing=6)
        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        sw = ScrolledWindow()
        sw.set_shadow_type(gtk.SHADOW_IN)
        self.view = view = CollectionView()
        view.set_headers_visible(False)
        model_sort = gtk.TreeModelSort(self.__model)
        model_filter = model_sort.filter_new()
        self.__filter = None
        self.__bg_filter = background_filter()
        model_filter.set_visible_func(self.__parse_query)
        view.set_model(model_filter)

        def sort(model, i1, i2):
            t1, t2 = model[i1][0], model[i2][0]
            if t1 is None or t2 is None:
                # FIXME: why?
                return 0

            # FIXME: order this deterministically
            if t1 is MultiNode or t1 is UnknownNode or \
                    t2 is MultiNode or t2 is UnknownNode:
                return -cmp(t1, t2)

            if not isinstance(t1, Album):
                return cmp(util.human_sort_key(t1), util.human_sort_key(t2))

            a1, a2 = t1, t2
            return (cmp(a1.peoplesort and a1.peoplesort[0],
                        a2.peoplesort and a2.peoplesort[0]) or
                        cmp(a1.date or "ZZZZ", a2.date or "ZZZZ") or
                        cmp((a1.sort, a1.key), (a2.sort, a2.key)))

        model_sort.set_sort_func(0, sort)
        model_sort.set_sort_column_id(0, gtk.SORT_ASCENDING)

        column = gtk.TreeViewColumn("albums")

        def cell_data(column, cell, model, iter_):
            markup = StoreUtils.get_markup(model, self.__model.tags, iter_)
            cell.markup = markup
            cell.set_property('markup', markup)

        def cell_data_pb(column, cell, model, iter_):
            album = StoreUtils.get_album(model, iter_)
            if album is None:
                cell.set_property('stock_id', gtk.STOCK_DIRECTORY)
            else:
                album.scan_cover()
                if album.cover:
                    cell.set_property('pixbuf', scale(album.cover, (25, 25)))
                else:
                    cell.set_property('stock_id', gtk.STOCK_CDROM)

        imgrender = gtk.CellRendererPixbuf()
        render = gtk.CellRendererText()
        render.set_property('ellipsize', pango.ELLIPSIZE_END)
        column.pack_start(imgrender, False)
        column.pack_start(render, True)
        column.set_cell_data_func(render, cell_data)
        column.set_cell_data_func(imgrender, cell_data_pb)
        view.append_column(column)

        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        sw.add(view)

        hbox = gtk.HBox(spacing=6)

        prefs = gtk.Button()
        prefs.add(gtk.image_new_from_stock(
            gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU))
        prefs.connect('clicked', Preferences)

        search = SearchBarBox(button=False, completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)

        search.connect('query-changed', self.__update_filter)

        hbox.pack_start(search)
        hbox.pack_start(prefs, expand=False)

        if main:
            self.pack_start(Alignment(hbox, left=3, top=3), expand=False)
        else:
            self.pack_start(hbox, expand=False)

        self.pack_start(sw, expand=True)

        view.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
        self.__sig = view.get_selection().connect('changed',
            self.__selection_changed)
        view.connect('row-activated', self.__play, main)
        view.connect_object('popup-menu', self.__popup, view, library)

        targets = [("text/x-quodlibet-songs", gtk.TARGET_SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        view.drag_source_set(
            gtk.gdk.BUTTON1_MASK, targets, gtk.gdk.ACTION_COPY)
        view.connect("drag-data-get", self.__drag_data_get)

        self.connect("destroy", self.__destroy)

        self.show_all()
Пример #29
0
    def __init__(self, library):
        super(AlbumList, self).__init__(spacing=6)
        self.set_orientation(Gtk.Orientation.VERTICAL)

        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        self._cover_cancel = Gio.Cancellable.new()

        sw = ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        self.view = view = AllTreeView()
        view.set_headers_visible(False)
        model_sort = AlbumSortModel(model=self.__model)
        model_filter = AlbumFilterModel(child_model=model_sort)

        self.__bg_filter = background_filter()
        self.__filter = None
        model_filter.set_visible_func(self.__parse_query)

        render = Gtk.CellRendererPixbuf()
        self.__cover_column = column = Gtk.TreeViewColumn("covers", render)
        column.set_visible(config.getboolean("browsers", "album_covers"))
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        column.set_fixed_width(Album.COVER_SIZE + 12)
        render.set_property('height', Album.COVER_SIZE + 8)
        render.set_property('width', Album.COVER_SIZE + 8)

        def cell_data_pb(column, cell, model, iter_, no_cover):
            album = model.get_album(iter_)

            if album is None:
                pixbuf = None
            elif album.cover:
                pixbuf = album.cover
                round_ = config.getboolean("albumart", "round")
                pixbuf = add_border_widget(pixbuf, self.view, round_)
                pixbuf = get_pbosf_for_pixbuf(self, pixbuf)
                # don't cache, too much state has an effect on the result
                self.__last_render_pb = None
            else:
                pixbuf = no_cover

            if self.__last_render_pb == pixbuf:
                return
            self.__last_render_pb = pixbuf
            set_renderer_from_pbosf(cell, pixbuf)

        column.set_cell_data_func(render, cell_data_pb, self._no_cover)
        view.append_column(column)

        render = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("albums", render)
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        if view.supports_hints():
            render.set_property('ellipsize', Pango.EllipsizeMode.END)

        def cell_data(column, cell, model, iter_, data):
            album = model.get_album(iter_)

            if album is None:
                text = "<b>%s</b>" % _("All Albums")
                text += "\n" + ngettext("%d album", "%d albums",
                        len(model) - 1) % (len(model) - 1)
                markup = text
            else:
                markup = self.display_pattern % album

            if self.__last_render == markup:
                return
            self.__last_render = markup
            cell.markup = markup
            cell.set_property('markup', markup)

        column.set_cell_data_func(render, cell_data)
        view.append_column(column)

        view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        view.set_rules_hint(True)
        view.set_search_equal_func(self.__search_func, None)
        view.set_search_column(0)
        view.set_model(model_filter)
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.add(view)

        view.connect('row-activated', self.__play_selection)
        self.__sig = view.connect('selection-changed',
            util.DeferredSignal(self.__update_songs, owner=view))

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        view.drag_source_set(
            Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY)
        view.connect("drag-data-get", self.__drag_data_get)
        connect_obj(view, 'popup-menu', self.__popup, view, library)

        self.accelerators = Gtk.AccelGroup()
        search = SearchBarBox(completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)
        search.connect('query-changed', self.__update_filter)
        connect_obj(search, 'focus-out', lambda w: w.grab_focus(), view)
        self.__search = search

        prefs = PreferencesButton(self, model_sort)
        search.pack_start(prefs, False, True, 0)
        self.pack_start(Align(search, left=6, top=6), False, True, 0)
        self.pack_start(sw, True, True, 0)

        self.connect("destroy", self.__destroy)

        self.enable_row_update(view, sw, self.__cover_column)

        self.connect('key-press-event', self.__key_pressed, library.librarian)

        self.show_all()
Пример #30
0
 def __browser_cb(self, browser, songs, sorted):
     if browser.background:
         bg = background_filter()
         if bg:
             songs = filter(bg, songs)
     self.songlist.set_songs(songs, sorted)
Пример #31
0
    def __init__(self, library):
        Browser.__init__(self, spacing=6)
        self.set_orientation(Gtk.Orientation.VERTICAL)

        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        self._cover_cancel = Gio.Cancellable.new()

        self.scrollwin = sw = ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        model_sort = AlbumSortModel(model=self.__model)
        model_filter = AlbumFilterModel(child_model=model_sort)
        self.view = view = Gtk.IconView(model_filter)
        #view.set_item_width(get_cover_size() + 12)
        self.view.set_row_spacing(config.getint("browsers", "row_spacing", 6))
        self.view.set_column_spacing(config.getint("browsers",
            "column_spacing", 6))
        self.view.set_item_padding(config.getint("browsers",
            "item_padding", 6))
        self.view.set_has_tooltip(True)
        self.view.connect("query-tooltip", self._show_tooltip)

        self.__bg_filter = background_filter()
        self.__filter = None
        model_filter.set_visible_func(self.__parse_query)

        mag = config.getfloat("browsers", "covergrid_magnification", 3.)

        self.view.set_item_width(get_cover_size() * mag + 8)

        self.__cover = render = Gtk.CellRendererPixbuf()
        render.set_property('width', get_cover_size() * mag + 8)
        render.set_property('height', get_cover_size() * mag + 8)
        view.pack_start(render, False)

        def cell_data_pb(view, cell, model, iter_, no_cover):
            item = model.get_value(iter_)

            if item.album is None:
                surface = None
            elif item.cover:
                pixbuf = item.cover
                pixbuf = add_border_widget(pixbuf, self.view)
                surface = get_surface_for_pixbuf(self, pixbuf)
                # don't cache, too much state has an effect on the result
                self.__last_render_surface = None
            else:
                surface = no_cover

            if self.__last_render_surface == surface:
                return
            self.__last_render_surface = surface
            cell.set_property("surface", surface)

        view.set_cell_data_func(render, cell_data_pb, self._no_cover)

        self.__text_cells = render = Gtk.CellRendererText()
        render.set_visible(config.getboolean("browsers", "album_text", True))
        render.set_property('alignment', Pango.Alignment.CENTER)
        render.set_property('xalign', 0.5)
        render.set_property('ellipsize', Pango.EllipsizeMode.END)
        view.pack_start(render, False)

        def cell_data(view, cell, model, iter_, data):
            album = model.get_album(iter_)

            if album is None:
                text = "<b>%s</b>" % _("All Albums")
                text += "\n" + ngettext("%d album", "%d albums",
                        len(model) - 1) % (len(model) - 1)
                markup = text
            else:
                markup = self.display_pattern % album

            if self.__last_render == markup:
                return
            self.__last_render = markup
            cell.markup = markup
            cell.set_property('markup', markup)

        view.set_cell_data_func(render, cell_data, None)

        view.set_selection_mode(Gtk.SelectionMode.MULTIPLE)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.add(view)

        view.connect('item-activated', self.__play_selection, None)

        self.__sig = connect_destroy(
            view, 'selection-changed',
            util.DeferredSignal(self.__update_songs, owner=self))

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        view.drag_source_set(
            Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY)
        view.connect("drag-data-get", self.__drag_data_get)
        connect_obj(view, 'popup-menu', self.__popup, view, library)

        self.accelerators = Gtk.AccelGroup()
        search = SearchBarBox(completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)
        search.connect('query-changed', self.__update_filter)
        connect_obj(search, 'focus-out', lambda w: w.grab_focus(), view)
        self.__search = search

        prefs = PreferencesButton(self, model_sort)
        search.pack_start(prefs, False, True, 0)
        self.pack_start(Align(search, left=6, top=6), False, True, 0)
        self.pack_start(sw, True, True, 0)

        self.connect("destroy", self.__destroy)

        self.enable_row_update(view, sw, self.view)

        self.connect('key-press-event', self.__key_pressed, library.librarian)

        if app.cover_manager:
            connect_destroy(
                app.cover_manager, "cover-changed", self._cover_changed)

        self.show_all()
Пример #32
0
    def __init__(self, library, main):
        super(AlbumList, self).__init__(spacing=6)
        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        sw = ScrolledWindow()
        sw.set_shadow_type(gtk.SHADOW_IN)
        self.view = view = AllTreeView()
        view.set_headers_visible(False)
        model_sort = gtk.TreeModelSort(self.__model)
        model_filter = model_sort.filter_new()

        self.__bg_filter = background_filter()
        self.__filter = None
        model_filter.set_visible_func(self.__parse_query)

        render = gtk.CellRendererPixbuf()
        self.__cover_column = column = gtk.TreeViewColumn("covers", render)
        column.set_visible(config.getboolean("browsers", "album_covers"))
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        column.set_fixed_width(60)
        render.set_property('height', 56)

        def cell_data_pb(column, cell, model, iter, no_cover):
            album = model[iter][0]
            if album is None: pixbuf = None
            elif album.cover: pixbuf = album.cover
            else: pixbuf = no_cover
            if self.__last_render_pb == pixbuf: return
            self.__last_render_pb = pixbuf
            cell.set_property('pixbuf', pixbuf)

        column.set_cell_data_func(render, cell_data_pb, self.__no_cover)
        view.append_column(column)

        render = gtk.CellRendererText()
        column = gtk.TreeViewColumn("albums", render)
        render.set_property('ellipsize', pango.ELLIPSIZE_END)

        def cell_data(column, cell, model, iter):
            album = model[iter][0]
            if album is None:
                text = "<b>%s</b>" % _("All Albums")
                text += "\n" + ngettext("%d album", "%d albums",
                        len(model) - 1) % (len(model) - 1)
                markup = text
            else:
                markup = AlbumList._pattern % album

            if self.__last_render == markup: return
            self.__last_render = markup
            cell.markup = markup
            cell.set_property('markup', markup)

        column.set_cell_data_func(render, cell_data)
        view.append_column(column)

        view.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
        view.set_rules_hint(True)
        view.set_search_equal_func(self.__search_func)
        view.set_search_column(0)
        view.set_model(model_filter)
        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        sw.add(view)

        if main:
            gobject_weak(view.connect, 'row-activated',
                self.__play_selection)

        self.__sig = gobject_weak(view.get_selection().connect, 'changed',
            util.DeferredSignal(self.__update_songs), parent=view)

        targets = [("text/x-quodlibet-songs", gtk.TARGET_SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        view.drag_source_set(
            gtk.gdk.BUTTON1_MASK, targets, gtk.gdk.ACTION_COPY)
        gobject_weak(view.connect, "drag-data-get", self.__drag_data_get)
        gobject_weak(view.connect_object, 'popup-menu',
            self.__popup, view, library)

        self.accelerators = gtk.AccelGroup()
        search = SearchBarBox(button=False, completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)
        gobject_weak(search.connect, 'query-changed', self.__update_filter)
        gobject_weak(search.connect_object,
                     'focus-out', lambda w: w.grab_focus(), view)
        self.__search = search

        prefs = PreferencesButton(model_sort)
        search.pack_start(prefs, expand=False)
        if main:
            self.pack_start(Alignment(search, left=3, top=3), expand=False)
        else:
            self.pack_start(search, expand=False)

        self.pack_start(sw, expand=True)

        self.connect("destroy", self.__destroy)

        self.enable_row_update(view, sw, self.__cover_column)

        self.show_all()
Пример #33
0
 def __browser_cb(self, browser, songs, sorted):
     if browser.background:
         bg = background_filter()
         if bg: songs = filter(bg, songs)
     self.__set_time(songs=songs)
     self.songlist.set_songs(songs, sorted)
Пример #34
0
    def __init__(self, library):
        super(CollectionBrowser, self).__init__(spacing=6)
        self.set_orientation(Gtk.Orientation.VERTICAL)

        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        sw = ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        self.view = view = CollectionView()
        view.set_headers_visible(False)
        model_sort = CollectionSortModel(model=self.__model)
        model_filter = CollectionFilterModel(child_model=model_sort)
        self.__filter = None
        self.__bg_filter = background_filter()
        model_filter.set_visible_func(self.__parse_query)
        view.set_model(model_filter)

        def cmpa(a, b):
            """Like cmp but treats values that evaluate to false as inf"""
            if not a and b:
                return 1
            if not b and a:
                return -1
            return cmp(a, b)

        def cmp_rows(model, i1, i2, data):
            t1, t2 = model[i1][0], model[i2][0]
            pos1 = _ORDERING.get(t1, 0)
            pos2 = _ORDERING.get(t2, 0)
            if pos1 or pos2:
                return cmp(pos1, pos2)

            if not isinstance(t1, AlbumNode):
                return cmp(util.human_sort_key(t1), util.human_sort_key(t2))

            a1, a2 = t1.album, t2.album
            return (cmpa(a1.peoplesort, a2.peoplesort)
                    or cmpa(a1.date, a2.date) or cmpa(a1.sort, a2.sort)
                    or cmp(a1.key, a2.key))

        model_sort.set_sort_func(0, cmp_rows)
        model_sort.set_sort_column_id(0, Gtk.SortType.ASCENDING)

        column = Gtk.TreeViewColumn("albums")

        def cell_data(column, cell, model, iter_, data):
            markup = model.get_markup(self.__model.tags, iter_)
            cell.markup = markup
            cell.set_property('markup', markup)

        def get_scaled_cover(item):
            if item.scanned:
                return item.cover

            scale_factor = self.get_scale_factor()
            item.scan_cover(scale_factor=scale_factor)
            return item.cover

        def cell_data_pb(column, cell, model, iter_, data):
            album = model.get_album(iter_)
            if album is None:
                cell.set_property('icon-name', Icons.FOLDER)
            else:
                item = model.get_value(iter_)
                cover = get_scaled_cover(item)
                if cover:
                    cover = add_border_widget(cover, view)
                    surface = get_surface_for_pixbuf(self, cover)
                    cell.set_property("surface", surface)
                else:
                    cell.set_property('icon-name', Icons.MEDIA_OPTICAL)

        imgrender = Gtk.CellRendererPixbuf()
        render = Gtk.CellRendererText()
        if view.supports_hints():
            render.set_property('ellipsize', Pango.EllipsizeMode.END)
        column.pack_start(imgrender, False)
        column.pack_start(render, True)
        column.set_cell_data_func(render, cell_data)
        column.set_cell_data_func(imgrender, cell_data_pb)
        view.append_column(column)

        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.add(view)

        hbox = Gtk.HBox(spacing=6)

        prefs = Gtk.Button()
        prefs.add(SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU))
        prefs.connect('clicked', lambda *x: Preferences(self))

        self.accelerators = Gtk.AccelGroup()
        search = SearchBarBox(completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)
        search.connect('query-changed', self.__update_filter)
        connect_obj(search, 'focus-out', lambda w: w.grab_focus(), view)
        self.__search = search

        hbox.pack_start(search, True, True, 0)
        hbox.pack_start(prefs, False, True, 0)

        self.pack_start(Align(hbox, left=6, top=6), False, True, 0)
        self.pack_start(sw, True, True, 0)

        view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.__sig = view.get_selection().connect('changed',
                                                  self.__selection_changed)
        view.connect('row-activated', self.__play)
        connect_obj(view, 'popup-menu', self.__popup, view, library)

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        view.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, targets,
                             Gdk.DragAction.COPY)
        view.connect("drag-data-get", self.__drag_data_get)

        self.connect("destroy", self.__destroy)

        self.show_all()
Пример #35
0
    def __init__(self, library, main):
        super(AlbumList, self).__init__(spacing=6)
        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        sw = ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        self.view = view = AllTreeView()
        view.set_headers_visible(False)
        model_sort = AlbumSortModel(model=self.__model)
        model_filter = AlbumFilterModel(child_model=model_sort)

        self.__bg_filter = background_filter()
        self.__filter = None
        model_filter.set_visible_func(self.__parse_query)

        render = Gtk.CellRendererPixbuf()
        self.__cover_column = column = Gtk.TreeViewColumn("covers", render)
        column.set_visible(config.getboolean("browsers", "album_covers"))
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        column.set_fixed_width(Album.COVER_SIZE + 12)
        render.set_property('height', Album.COVER_SIZE + 8)

        def cell_data_pb(column, cell, model, iter_, no_cover):
            album = model.get_album(iter_)
            if album is None:
                pixbuf = None
            elif album.cover:
                pixbuf = album.cover
            else:
                pixbuf = no_cover
            if self.__last_render_pb == pixbuf:
                return
            self.__last_render_pb = pixbuf
            cell.set_property('pixbuf', pixbuf)

        column.set_cell_data_func(render, cell_data_pb, self.__no_cover)
        view.append_column(column)

        render = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("albums", render)
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        render.set_property('ellipsize', Pango.EllipsizeMode.END)

        def cell_data(column, cell, model, iter_, data):
            album = model.get_album(iter_)

            if album is None:
                text = "<b>%s</b>" % _("All Albums")
                text += "\n" + ngettext("%d album", "%d albums",
                        len(model) - 1) % (len(model) - 1)
                markup = text
            else:
                markup = AlbumList._pattern % album

            if self.__last_render == markup:
                return
            self.__last_render = markup
            cell.markup = markup
            cell.set_property('markup', markup)

        column.set_cell_data_func(render, cell_data)
        view.append_column(column)

        view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        view.set_rules_hint(True)
        view.set_search_equal_func(self.__search_func, None)
        view.set_search_column(0)
        view.set_model(model_filter)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.add(view)

        if main:
            gobject_weak(view.connect, 'row-activated',
                         self.__play_selection)

        self.__sig = gobject_weak(
            view.get_selection().connect, 'changed',
            util.DeferredSignal(self.__update_songs), parent=view)

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        view.drag_source_set(
            Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY)
        gobject_weak(view.connect, "drag-data-get", self.__drag_data_get)
        gobject_weak(view.connect_object, 'popup-menu',
                     self.__popup, view, library)

        self.accelerators = Gtk.AccelGroup()
        search = SearchBarBox(completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)
        gobject_weak(search.connect, 'query-changed', self.__update_filter)
        gobject_weak(search.connect_object,
                     'focus-out', lambda w: w.grab_focus(), view)
        self.__search = search

        prefs = PreferencesButton(self, model_sort)
        search.pack_start(prefs, False, True, 0)
        if main:
            self.pack_start(Alignment(search, left=6, top=6), False, True, 0)
        else:
            self.pack_start(search, False, True, 0)

        self.pack_start(sw, True, True, 0)

        self.connect("destroy", self.__destroy)

        self.enable_row_update(view, sw, self.__cover_column)

        self.connect('key-press-event', self.__key_pressed, library.librarian)

        self.show_all()
Пример #36
0
    def __init__(self, library):
        Browser.__init__(self, spacing=6)
        self.set_orientation(Gtk.Orientation.VERTICAL)
        self.songcontainer = qltk.paned.ConfigRVPaned(
            "browsers", "covergrid_pos", 0.4)
        if config.getboolean("browsers", "covergrid_wide", False):
            self.songcontainer.set_orientation(Gtk.Orientation.HORIZONTAL)

        self._register_instance()
        if self.__model is None:
            self._init_model(library)

        self._cover_cancel = Gio.Cancellable()

        self.scrollwin = sw = ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        model_sort = AlbumSortModel(model=self.__model)
        model_filter = AlbumFilterModel(child_model=model_sort)
        self.view = view = IconView(model_filter)
        #view.set_item_width(get_cover_size() + 12)
        self.view.set_row_spacing(config.getint("browsers", "row_spacing", 6))
        self.view.set_column_spacing(config.getint("browsers",
            "column_spacing", 6))
        self.view.set_item_padding(config.getint("browsers",
            "item_padding", 6))
        self.view.set_has_tooltip(True)
        self.view.connect("query-tooltip", self._show_tooltip)

        self.__bg_filter = background_filter()
        self.__filter = None
        model_filter.set_visible_func(self.__parse_query)

        mag = config.getfloat("browsers", "covergrid_magnification", 3.)

        self.view.set_item_width(get_cover_size() * mag + 8)

        self.__cover = render = Gtk.CellRendererPixbuf()
        render.set_property('width', get_cover_size() * mag + 8)
        render.set_property('height', get_cover_size() * mag + 8)
        view.pack_start(render, False)

        def cell_data_pb(view, cell, model, iter_, no_cover):
            item = model.get_value(iter_)

            if item.album is None:
                surface = None
            elif item.cover:
                pixbuf = item.cover
                pixbuf = add_border_widget(pixbuf, self.view)
                surface = get_surface_for_pixbuf(self, pixbuf)
                # don't cache, too much state has an effect on the result
                self.__last_render_surface = None
            else:
                surface = no_cover

            if self.__last_render_surface == surface:
                return
            self.__last_render_surface = surface
            cell.set_property("surface", surface)

        view.set_cell_data_func(render, cell_data_pb, self._no_cover)

        self.__text_cells = render = Gtk.CellRendererText()
        render.set_visible(config.getboolean("browsers", "album_text", True))
        render.set_property('alignment', Pango.Alignment.CENTER)
        render.set_property('xalign', 0.5)
        render.set_property('ellipsize', Pango.EllipsizeMode.END)
        view.pack_start(render, False)

        def cell_data(view, cell, model, iter_, data):
            album = model.get_album(iter_)

            if album is None:
                text = "<b>%s</b>" % _("All Albums")
                text += "\n" + ngettext("%d album", "%d albums",
                        len(model) - 1) % (len(model) - 1)
                markup = text
            else:
                markup = self.display_pattern % album

            if self.__last_render == markup:
                return
            self.__last_render = markup
            cell.markup = markup
            cell.set_property('markup', markup)

        view.set_cell_data_func(render, cell_data, None)

        view.set_selection_mode(Gtk.SelectionMode.MULTIPLE)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.add(view)

        view.connect('item-activated', self.__play_selection, None)

        self.__sig = connect_destroy(
            view, 'selection-changed',
            util.DeferredSignal(self.__update_songs, owner=self))

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1),
                   ("text/uri-list", 0, 2)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        view.drag_source_set(
            Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY)
        view.connect("drag-data-get", self.__drag_data_get) # NOT WORKING
        connect_obj(view, 'button-press-event',
            self.__rightclick, view, library)
        connect_obj(view, 'popup-menu', self.__popup, view, library)

        self.accelerators = Gtk.AccelGroup()
        search = SearchBarBox(completion=AlbumTagCompletion(),
                              accel_group=self.accelerators)
        search.connect('query-changed', self.__update_filter)
        connect_obj(search, 'focus-out', lambda w: w.grab_focus(), view)
        self.__search = search

        prefs = PreferencesButton(self, model_sort)
        search.pack_start(prefs, False, True, 0)
        self.pack_start(Align(search, left=6, top=6), False, True, 0)
        self.pack_start(sw, True, True, 0)

        self.connect("destroy", self.__destroy)

        self.enable_row_update(view, sw, self.view)

        self.__update_filter()

        self.connect('key-press-event', self.__key_pressed, library.librarian)

        if app.cover_manager:
            connect_destroy(
                app.cover_manager, "cover-changed", self._cover_changed)

        self.show_all()