def test_get_query(self): sbb = SearchBarBox() self.failIf(sbb.get_query(None)) a_star = ["artist", "date", "custom"] sbb.set_text("foobar") expected = Query("foobar", star=a_star) self.failUnlessEqual(sbb.get_query(a_star), expected)
def __create_searchbar(self, library): self.accelerators = Gtk.AccelGroup() completion = LibraryTagCompletion(library.librarian) sbb = SearchBarBox(completion=completion, accel_group=self.accelerators) sbb.connect("query-changed", self.__text_parse) sbb.connect("focus-out", self.__focus) return sbb
def __init__(self, library, main, limit=True): super(SearchBar, self).__init__(library, main) self.set_spacing(6) completion = LibraryTagCompletion(library.librarian) self.accelerators = gtk.AccelGroup() if limit: self._search_bar = LimitSearchBar(completion=completion, accel_group=self.accelerators) else: self._search_bar = SearchBarBox(completion=completion, accel_group=self.accelerators) self._search_bar.connect('query-changed', self.__text_parse) def focus(widget, *args): qltk.get_top_parent(widget).songlist.grab_focus() self._search_bar.connect('focus-out', focus) self.connect('destroy', self.__destroy) if main: align = Alignment(self._search_bar, left=3, right=3, top=3) else: align = Alignment(self._search_bar) align.show() self.pack_start(align, expand=False) self.show()
def test_get_query_override_star(self): sbb = SearchBarBox(star=["initial"]) text = "foobar" sbb.set_text(text) self.failUnlessEqual(sbb.get_query(), Query(text, star=["initial"])) another_star = ["another", "star"] self.failUnlessEqual(sbb.get_query(star=another_star), Query(text, star=another_star))
def __init__(self, library, main): super(PanedBrowser, self).__init__() self._register_instance() self.__main = main self._filter = None self._library = library self.commands = {"query": self.__query} self.set_spacing(6) completion = LibraryTagCompletion(library.librarian) self.accelerators = Gtk.AccelGroup() sbb = SearchBarBox(completion=completion, accel_group=self.accelerators) sbb.connect('query-changed', self.__text_parse) sbb.connect('focus-out', self.__focus) self._sb_box = sbb align = (Alignment(sbb, left=6, right=6, top=6) if main else Alignment(sbb)) self.pack_start(align, False, True, 0) keyval, mod = Gtk.accelerator_parse("<control>Home") s = self.accelerators.connect(keyval, mod, 0, self.__select_all) self.connect_object('destroy', self.accelerators.disconnect_key, keyval, mod) select = Gtk.Button(_("Select _All"), use_underline=True) s = select.connect('clicked', self.__select_all) self.connect_object('destroy', select.disconnect, s) sbb.pack_start(select, False, True, 0) prefs = PreferencesButton(self) sbb.pack_start(prefs, False, True, 0) for s in [ library.connect('changed', self.__changed), library.connect('added', self.__added), library.connect('removed', self.__removed) ]: self.connect_object('destroy', library.disconnect, s) self.connect('destroy', self.__destroy) # contains the panes and the song list self.main_box = RPaned() self.pack_start(self.main_box, True, True, 0) self.refresh_panes() for child in self.get_children(): child.show_all()
def _create_searchbar(self, library): completion = LibraryTagCompletion(library) self.accelerators = Gtk.AccelGroup() search = SearchBarBox(completion=completion, validator=SoundcloudQuery.validator, accel_group=self.accelerators, timeout=3000) self.__searchbar = search search.connect('query-changed', self.__query_changed) def focus(widget, *args): qltk.get_top_parent(widget).songlist.grab_focus() search.connect('focus-out', focus) self._searchbox = Align(search, left=0, right=6, top=6) self._searchbox.show_all()
def __init__(self, library): super(PanedBrowser, self).__init__() self._register_instance() self._filter = lambda s: False self._library = library self.set_spacing(6) self.set_orientation(Gtk.Orientation.VERTICAL) completion = LibraryTagCompletion(library.librarian) self.accelerators = Gtk.AccelGroup() sbb = SearchBarBox(completion=completion, accel_group=self.accelerators) sbb.connect('query-changed', self.__text_parse) sbb.connect('focus-out', self.__focus) self._sb_box = sbb align = Align(sbb, left=6, right=6, top=6) self.pack_start(align, False, True, 0) keyval, mod = Gtk.accelerator_parse("<Primary>Home") self.accelerators.connect(keyval, mod, 0, self.__select_all) select = Gtk.Button(label=_("Select _All"), use_underline=True) select.connect('clicked', self.__select_all) sbb.pack_start(select, False, True, 0) prefs = PreferencesButton(self) sbb.pack_start(prefs, False, True, 0) connect_destroy(library, 'changed', self.__changed) connect_destroy(library, 'added', self.__added) connect_destroy(library, 'removed', self.__removed) self.connect('destroy', self.__destroy) # contains the panes and the song list self.main_box = qltk.ConfigRPaned("browsers", "panedbrowser_pos", 0.4) self.pack_start(self.main_box, True, True, 0) self.multi_paned = ConfigMultiRHPaned("browsers", "panedbrowser_pane_widths") self.refresh_panes() for child in self.get_children(): child.show_all()
def __create_searchbar(self, library): self.accelerators = Gtk.AccelGroup() completion = LibraryTagCompletion(library.librarian) sbb = SearchBarBox(completion=completion, accel_group=self.accelerators) sbb.connect('query-changed', self.__text_parse) sbb.connect('focus-out', self.__focus) return sbb
class SearchBar(EmptyBar): name = _("Search Library") accelerated_name = _("_Search Library") priority = 1 in_menu = True def __init__(self, library, main, limit=True): super(SearchBar, self).__init__(library, main) self.set_spacing(6) completion = LibraryTagCompletion(library.librarian) self.accelerators = gtk.AccelGroup() if limit: self._search_bar = LimitSearchBar(completion=completion, accel_group=self.accelerators) else: self._search_bar = SearchBarBox(completion=completion, accel_group=self.accelerators) self._search_bar.connect('query-changed', self.__text_parse) def focus(widget, *args): qltk.get_top_parent(widget).songlist.grab_focus() self._search_bar.connect('focus-out', focus) self.connect('destroy', self.__destroy) if main: align = Alignment(self._search_bar, left=3, right=3, top=3) else: align = Alignment(self._search_bar) align.show() self.pack_start(align, expand=False) self.show() def __destroy(self, *args): self._search_bar = None def activate(self): songs = self._get_songs() if songs is not None and self._search_bar: songs = self._search_bar.limit(songs) gobject.idle_add(self.emit, 'songs-selected', songs, None) def __text_parse(self, bar, text): self._text = text self.activate() def filter_text(self, text): self._text = text self._search_bar.set_text(text) self.activate()
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()
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()
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()
def __init__(self, library): super(InternetRadio, self).__init__(spacing=12) self.set_orientation(Gtk.Orientation.VERTICAL) if not self.instances(): self._init(library) self._register_instance() self.connect('destroy', self.__destroy) completion = LibraryTagCompletion(self.__stations) self.accelerators = Gtk.AccelGroup() self.__searchbar = search = SearchBarBox(completion=completion, accel_group=self.accelerators) search.connect('query-changed', self.__filter_changed) menu = Gtk.Menu() new_item = MenuItem(_(u"_New Station…"), Icons.LIST_ADD) new_item.connect('activate', self.__add) menu.append(new_item) update_item = MenuItem(_("_Update Stations"), Icons.VIEW_REFRESH) update_item.connect('activate', self.__update) menu.append(update_item) menu.show_all() button = MenuButton(SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU), arrow=True) button.set_menu(menu) def focus(widget, *args): qltk.get_top_parent(widget).songlist.grab_focus() search.connect('focus-out', focus) # treeview scrolled_window = ScrolledWindow() scrolled_window.show() scrolled_window.set_shadow_type(Gtk.ShadowType.IN) self.view = view = AllTreeView() view.show() view.set_headers_visible(False) scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolled_window.add(view) model = Gtk.ListStore(int, str, str, str) model.append( row=[self.TYPE_ALL, Icons.FOLDER, "__all", _("All Stations")]) model.append(row=[self.TYPE_SEP, Icons.FOLDER, "", ""]) #Translators: Favorite radio stations model.append( row=[self.TYPE_FAV, Icons.FOLDER, "__fav", _("Favorites")]) model.append(row=[self.TYPE_SEP, Icons.FOLDER, "", ""]) filters = self.filters for text, k in sorted([(filters.text(k), k) for k in filters.keys()]): model.append(row=[self.TYPE_FILTER, Icons.EDIT_FIND, k, text]) model.append( row=[self.TYPE_NOCAT, Icons.FOLDER, "nocat", _("No Category")]) def separator(model, iter, data): return model[iter][self.TYPE] == self.TYPE_SEP view.set_row_separator_func(separator, None) def search_func(model, column, key, iter, data): return key.lower() not in model[iter][column].lower() view.set_search_column(self.NAME) view.set_search_equal_func(search_func, None) column = Gtk.TreeViewColumn("genres") column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) renderpb = Gtk.CellRendererPixbuf() renderpb.props.xpad = 3 column.pack_start(renderpb, False) column.add_attribute(renderpb, "icon-name", self.ICON_NAME) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) view.append_column(column) column.pack_start(render, True) column.add_attribute(render, "text", self.NAME) view.set_model(model) # selection selection = view.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) self.__changed_sig = connect_destroy( selection, 'changed', util.DeferredSignal(lambda x: self.activate())) box = Gtk.HBox(spacing=6) box.pack_start(search, True, True, 0) box.pack_start(button, False, True, 0) self._searchbox = Align(box, left=0, right=6, top=6) self._searchbox.show_all() def qbar_response(infobar, response_id): if response_id == infobar.RESPONSE_LOAD: self.__update() self.qbar = QuestionBar() self.qbar.connect("response", qbar_response) if self._is_library_empty(): self.qbar.show() pane = qltk.ConfigRHPaned("browsers", "internetradio_pos", 0.4) pane.show() pane.pack1(scrolled_window, resize=False, shrink=False) songbox = Gtk.VBox(spacing=6) songbox.pack_start(self._searchbox, False, True, 0) self._songpane_container = Gtk.VBox() self._songpane_container.show() songbox.pack_start(self._songpane_container, True, True, 0) songbox.pack_start(self.qbar, False, True, 0) songbox.show() pane.pack2(songbox, resize=True, shrink=False) self.pack_start(pane, True, True, 0) self.show()
def __init__(self, library, main): super(InternetRadio, self).__init__(spacing=12) if not self.instances(): self._init(library) self._register_instance() self.connect('destroy', self.__destroy) completion = LibraryTagCompletion(self.__stations) self.accelerators = Gtk.AccelGroup() self.__searchbar = search = SearchBarBox(completion=completion, accel_group=self.accelerators) gobject_weak(search.connect, 'query-changed', self.__filter_changed) menu = Gtk.Menu() new_item = MenuItem(_("_New Station..."), Gtk.STOCK_ADD) gobject_weak(new_item.connect, 'activate', self.__add) menu.append(new_item) update_item = MenuItem(_("_Update Stations"), Gtk.STOCK_REFRESH) gobject_weak(update_item.connect, 'activate', self.__update) menu.append(update_item) menu.show_all() button = MenuButton( SymbolicIconImage("emblem-system", Gtk.IconSize.MENU), arrow=True) button.set_menu(menu) def focus(widget, *args): qltk.get_top_parent(widget).songlist.grab_focus() gobject_weak(search.connect, 'focus-out', focus, parent=self) # treeview scrolled_window = ScrolledWindow() scrolled_window.set_shadow_type(Gtk.ShadowType.IN) self.view = view = AllTreeView() view.set_headers_visible(False) scrolled_window.set_policy( Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolled_window.add(view) model = Gtk.ListStore(int, str, str, str) model.append(row=[self.TYPE_ALL, Gtk.STOCK_DIRECTORY, "__all", _("All Stations")]) model.append(row=[self.TYPE_SEP, Gtk.STOCK_DIRECTORY, "", ""]) #Translators: Favorite radio stations model.append(row=[self.TYPE_FAV, Gtk.STOCK_DIRECTORY, "__fav", _("Favorites")]) model.append(row=[self.TYPE_SEP, Gtk.STOCK_DIRECTORY, "", ""]) filters = self.filters for text, k in sorted([(filters.text(k), k) for k in filters.keys()]): model.append(row=[self.TYPE_FILTER, Gtk.STOCK_FIND, k, text]) model.append(row=[self.TYPE_NOCAT, Gtk.STOCK_DIRECTORY, "nocat", _("No Category")]) def separator(model, iter, data): return model[iter][self.TYPE] == self.TYPE_SEP view.set_row_separator_func(separator, None) def search_func(model, column, key, iter, data): return key.lower() not in model[iter][column].lower() view.set_search_column(self.NAME) view.set_search_equal_func(search_func, None) column = Gtk.TreeViewColumn("genres") column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) renderpb = Gtk.CellRendererPixbuf() renderpb.props.xpad = 3 column.pack_start(renderpb, False) column.add_attribute(renderpb, "stock_id", self.STOCK) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) view.append_column(column) column.pack_start(render, True) column.add_attribute(render, "text", self.NAME) view.set_model(model) # selection selection = view.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) self.__changed_sig = gobject_weak(selection.connect, 'changed', util.DeferredSignal(lambda x: self.activate()), parent=view) box = Gtk.HBox(spacing=6) box.pack_start(search, True, True, 0) box.pack_start(button, False, True, 0) if main: self.pack_start(Alignment(box, left=6, right=6, top=6), True, True, 0) else: self.pack_start(box, True, True, 0) self.__filter_list = scrolled_window def qbar_response(infobar, response_id): if response_id == infobar.RESPONSE_LOAD: self.__update() self.qbar = QuestionBar() self.qbar.connect("response", qbar_response) if self._is_library_empty(): self.qbar.show() self.show_all()
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()
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()
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()
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()
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()
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()
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()