def __init__(self, library, player, ui=None): self._browser = None self._library = library self._player = player self._standalone = not ui ag = Gtk.ActionGroup.new('QuodLibetFilterActions') for name, icon_name, label, cb in [ ('Filters', "", _("_Filters"), None), ("PlayedRecently", Icons.EDIT_FIND, _("Recently _Played"), self.__filter_menu_actions), ("AddedRecently", Icons.EDIT_FIND, _("Recently _Added"), self.__filter_menu_actions), ("TopRated", Icons.EDIT_FIND, _("_Top 40"), self.__filter_menu_actions), ("All", Icons.EDIT_FIND, _("All _Songs"), self.__filter_menu_actions) ]: action = Action(name=name, icon_name=icon_name, label=label) if cb: action.connect('activate', cb) ag.add_action(action) for tag_, lab in [("genre", _("On Current _Genre(s)")), ("artist", _("On Current _Artist(s)")), ("album", _("On Current Al_bum"))]: act = Action(name="Filter%s" % util.capitalize(tag_), label=lab, icon_name=Icons.EDIT_SELECT_ALL) act.connect('activate', self.__filter_on, tag_, None, player) ag.add_action(act) for (tag_, accel, label) in [("genre", "G", _("Random _Genre")), ("artist", "T", _("Random _Artist")), ("album", "M", _("Random Al_bum"))]: act = Action(name="Random%s" % util.capitalize(tag_), label=label, icon_name=Icons.DIALOG_QUESTION) act.connect('activate', self.__random, tag_) ag.add_action_with_accel(act, "<Primary>" + accel) if self._standalone: ui = Gtk.UIManager() ui.add_ui_from_string(self.__OUTER_MENU) ui.insert_action_group(ag, -1) self._ui = ui self._get_child_widget("TopRated").set_tooltip_text( _("The 40 songs you've played most (more than 40 may " "be chosen if there are ties)")) # https://git.gnome.org/browse/gtk+/commit/?id=b44df22895c79 menu_item = self._get_child_widget('/Menu/Filters') if isinstance(menu_item, Gtk.ImageMenuItem): menu_item.set_image(None) self._player_id = player.connect("song-started", self._on_song_started) self.set_song(player.song) self._hide_menus()
def _people(self, songs, box): artists = set([]) performers = set([]) for song in songs: artists.update(song.list("artist")) performers.update(song.list("performer")) artists = sorted(artists) performers = sorted(performers) if artists: if len(artists) == 1: title = _("artist") else: title = _("artists") title = util.capitalize(title) box.pack_start(Frame(title, Label("\n".join(artists))), False, False, 0) if performers: if len(artists) == 1: title = _("performer") else: title = _("performers") title = util.capitalize(title) box.pack_start(Frame(title, Label("\n".join(performers))), False, False, 0)
def __init__(self, library, player, ui=None): self._browser = None self._library = library self._player = player self._standalone = not ui ag = Gtk.ActionGroup.new('QuodLibetFilterActions') for name, icon_name, label, cb in [ ('Filters', "", _("_Filters"), None), ("PlayedRecently", Icons.EDIT_FIND, _("Recently _Played"), self.__filter_menu_actions), ("AddedRecently", Icons.EDIT_FIND, _("Recently _Added"), self.__filter_menu_actions), ("TopRated", Icons.EDIT_FIND, _("_Top 40"), self.__filter_menu_actions), ("All", Icons.EDIT_FIND, _("All _Songs"), self.__filter_menu_actions)]: action = Action(name=name, icon_name=icon_name, label=label) if cb: action.connect('activate', cb) ag.add_action(action) for tag_, lab in [ ("genre", _("On Current _Genre(s)")), ("artist", _("On Current _Artist(s)")), ("album", _("On Current Al_bum"))]: act = Action( name="Filter%s" % util.capitalize(tag_), label=lab, icon_name=Icons.EDIT_SELECT_ALL) act.connect('activate', self.__filter_on, tag_, None, player) ag.add_action(act) for (tag_, accel, label) in [ ("genre", "G", _("Random _Genre")), ("artist", "T", _("Random _Artist")), ("album", "M", _("Random Al_bum"))]: act = Action(name="Random%s" % util.capitalize(tag_), label=label, icon_name=Icons.DIALOG_QUESTION) act.connect('activate', self.__random, tag_) ag.add_action_with_accel(act, "<Primary>" + accel) if self._standalone: ui = Gtk.UIManager() ui.add_ui_from_string(self.__OUTER_MENU) ui.insert_action_group(ag, -1) self._ui = ui self._get_child_widget("TopRated").set_tooltip_text( _("The 40 songs you've played most (more than 40 may " "be chosen if there are ties)")) # https://git.gnome.org/browse/gtk+/commit/?id=b44df22895c79 menu_item = self._get_child_widget('/Menu/Filters') if isinstance(menu_item, Gtk.ImageMenuItem): menu_item.set_image(None) self._player_id = player.connect("song-started", self._on_song_started) self.set_song(player.song) self._hide_menus()
def _people(self, songs, box): artists = set() performers = set() for song in songs: artists.update(song.list("artist")) performers.update(song.list("performer")) artists = sorted(artists) performers = sorted(performers) if artists: if len(artists) == 1: title = _("artist") else: title = _("artists") title = util.capitalize(title) box.pack_start(Frame(title, Label("\n".join(artists))), False, False, 0) if performers: if len(artists) == 1: title = _("performer") else: title = _("performers") title = util.capitalize(title) box.pack_start(Frame(title, Label("\n".join(performers))), False, False, 0)
def _people(self, song, box): vb = Gtk.VBox() if "artist" in song: if len(song.list("artist")) == 1: title = _("artist") else: title = _("artists") title = util.capitalize(title) l = Label(song["artist"]) l.set_ellipsize(Pango.EllipsizeMode.END) vb.pack_start(l, False, True, 0) else: title = tag("~people") for names, tag_ in [ ("performers", "performer"), ("lyricists", "lyricist"), ("arrangers", "arranger"), ("composers", "composer"), ("conductors", "conductor"), ("authors", "author") ]: if tag_ in song: l = Label(song[tag_]) l.set_ellipsize(Pango.EllipsizeMode.END) if len(song.list(tag_)) == 1: name = tag(tag_) else: name = _(names) vb.pack_start(Frame(util.capitalize(name), l), False, False, 0) performers = {} for tag_ in song: if "performer:" in tag_: for person in song[tag_].split('\n'): try: performers[str(person)] except: performers[str(person)] = [] performers[str(person)].append( util.title(tag_[tag_.find(":") + 1:])) if len(performers) > 0: performerstr = '' for performer in performers: performerstr += performer + ' (' i = 0 for part in performers[performer]: if i != 0: performerstr += ', ' performerstr += part i += 1 performerstr += ')\n' l = Label(performerstr) l.set_ellipsize(Pango.EllipsizeMode.END) if len(performers) == 1: name = tag("performer") else: name = _("performers") vb.pack_start(Frame(util.capitalize(name), l), False, False, 0) if not vb.get_children(): vb.destroy() else: box.pack_start(Frame(title, vb), False, False, 0)
def _people(self, song, box): vb = Gtk.VBox() if "artist" in song: if len(song.list("artist")) == 1: title = _("artist") else: title = _("artists") title = util.capitalize(title) l = Label(song["artist"]) l.set_ellipsize(Pango.EllipsizeMode.END) vb.pack_start(l, False, True, 0) else: title = tag("~people") for tag_ in ["performer", "lyricist", "arranger", "composer", "conductor", "author"]: if tag_ in song: l = Label(song[tag_]) l.set_ellipsize(Pango.EllipsizeMode.END) if len(song.list(tag_)) == 1: name = tag(tag_) else: name = readable(tag_, plural=True) vb.pack_start(Frame(util.capitalize(name), l), False, False, 0) performers = {} for tag_ in song: if "performer:" in tag_: for person in song[tag_].split('\n'): try: performers[str(person)] except: performers[str(person)] = [] performers[str(person)].append( util.title(tag_[tag_.find(":") + 1:])) if len(performers) > 0: performerstr = '' for performer in performers: performerstr += performer + ' (' i = 0 for part in performers[performer]: if i != 0: performerstr += ', ' performerstr += part i += 1 performerstr += ')\n' l = Label(performerstr) l.set_ellipsize(Pango.EllipsizeMode.END) if len(performers) == 1: name = tag("performer") else: name = _("performers") vb.pack_start(Frame(util.capitalize(name), l), False, False, 0) if not vb.get_children(): vb.destroy() else: box.pack_start(Frame(title, vb), False, False, 0)
def __init__(self, library, player, ui=None): self._browser = None self._library = library self._player = player ag = Gtk.ActionGroup.new('QuodLibetFilterActions') ag.add_actions([ ('Filters', None, _("_Filters")), ("PlayedRecently", Gtk.STOCK_FIND, _("Recently _Played"), "", None, self.__filter_menu_actions), ("AddedRecently", Gtk.STOCK_FIND, _("Recently _Added"), "", None, self.__filter_menu_actions), ("TopRated", Gtk.STOCK_FIND, _("_Top 40"), "", None, self.__filter_menu_actions), ("All", Gtk.STOCK_FIND, _("All _Songs"), "", None, self.__filter_menu_actions), ]) for tag_, lab in [ ("genre", _("Filter on _Genre")), ("artist", _("Filter on _Artist")), ("album", _("Filter on Al_bum"))]: act = Gtk.Action.new( "Filter%s" % util.capitalize(tag_), lab, None, Gtk.STOCK_INDEX) act.connect('activate', self.__filter_on, tag_, None, player) ag.add_action_with_accel(act, None) for (tag_, accel, label) in [ ("genre", "G", _("Random _Genre")), ("artist", "T", _("Random _Artist")), ("album", "M", _("Random Al_bum"))]: act = Gtk.Action.new("Random%s" % util.capitalize(tag_), label, None, Gtk.STOCK_DIALOG_QUESTION) act.connect('activate', self.__random, tag_) ag.add_action_with_accel(act, "<control>" + accel) ui = ui or Gtk.UIManager() ui.insert_action_group(ag, -1) ui.add_ui_from_string(self._MENU) self._ui = ui ui.get_widget("/Menu/Filters/TopRated").set_tooltip_text( _("The 40 songs you've played most (more than 40 may " "be chosen if there are ties)")) # https://git.gnome.org/browse/gtk+/commit/?id=b44df22895c79 menu_item = ui.get_widget("/Menu/Filters") if isinstance(menu_item, Gtk.ImageMenuItem): menu_item.set_image(None) self._player_id = player.connect("song-started", self._on_song_started) self.set_song(player.song) self._hide_menus()
def __init__(self, library, player, ui=None): self._browser = None self._library = library self._player = player ag = Gtk.ActionGroup.new('QuodLibetFilterActions') ag.add_actions([ ('Filters', None, _("_Filters")), ("PlayedRecently", Gtk.STOCK_FIND, _("Recently _Played"), "", None, self.__filter_menu_actions), ("AddedRecently", Gtk.STOCK_FIND, _("Recently _Added"), "", None, self.__filter_menu_actions), ("TopRated", Gtk.STOCK_FIND, _("_Top 40"), "", None, self.__filter_menu_actions), ("All", Gtk.STOCK_FIND, _("All _Songs"), "", None, self.__filter_menu_actions), ]) for tag_, lab in [("genre", _("Filter on _Genre")), ("artist", _("Filter on _Artist")), ("album", _("Filter on Al_bum"))]: act = Gtk.Action.new("Filter%s" % util.capitalize(tag_), lab, None, Gtk.STOCK_INDEX) act.connect('activate', self.__filter_on, tag_, None, player) ag.add_action_with_accel(act, None) for (tag_, accel, label) in [("genre", "G", _("Random _Genre")), ("artist", "T", _("Random _Artist")), ("album", "M", _("Random Al_bum"))]: act = Gtk.Action.new("Random%s" % util.capitalize(tag_), label, None, Gtk.STOCK_DIALOG_QUESTION) act.connect('activate', self.__random, tag_) ag.add_action_with_accel(act, "<control>" + accel) ui = ui or Gtk.UIManager() ui.insert_action_group(ag, -1) ui.add_ui_from_string(self._MENU) self._ui = ui ui.get_widget("/Menu/Filters/TopRated").set_tooltip_text( _("The 40 songs you've played most (more than 40 may " "be chosen if there are ties)")) # https://git.gnome.org/browse/gtk+/commit/?id=b44df22895c79 menu_item = ui.get_widget("/Menu/Filters") if isinstance(menu_item, Gtk.ImageMenuItem): menu_item.set_image(None) self._player_id = player.connect("song-started", self._on_song_started) self.set_song(player.song) self._hide_menus()
def _people(self, songs, box): tags_ = PEOPLE people = defaultdict(set) for song in songs: for t in tags_: if t in song: people[t] |= set(song.list(t)) data = [] # Preserve order of people for tag_ in tags_: values = people.get(tag_) if values: name = readable(tag_, plural=len(values) > 1) data.append((name, "\n".join(values))) table = Table(len(data)) for i, (key, text) in enumerate(data): key = util.capitalize(util.escape(key) + ":") table.attach(Label(markup=key), 0, 1, i, i + 1, xoptions=Gtk.AttachOptions.FILL) label = Label(text, ellipsize=True) table.attach(label, 1, 2, i, i + 1) box.pack_start(Frame(tag("~people"), table), False, False, 0)
def _additional(self, song, box): if "website" not in song and "comment" not in song: return data = [] if "comment" in song: comments = song.list("comment") markups = ["<i>%s</i>" % c for c in comments] data.append(("comment", markups)) if "website" in song: markups = ["<a href=\"%(url)s\">%(text)s</a>" % {"text": util.escape(website), "url": util.escape(website)} for website in song.list("website")] data.append(("website", markups)) table = Table(1) for i, (key, markups) in enumerate(data): title = readable(key, plural=len(markups) > 1) lab = Label(markup=util.capitalize(util.escape(title) + ":")) table.attach(lab, 0, 1, i, i + 1, xoptions=Gtk.AttachOptions.FILL) lab = Label(markup="\n".join(markups), ellipsize=True) table.attach(lab, 1, 2, i, i + 1) box.pack_start(Frame(_("Additional"), table), False, False, 0)
def _library(self, song, box): def counter(i): return _("Never") if i == 0 \ else numeric_phrase("%(n)d time", "%(n)d times", i, "n") def ftime(t): if t == 0: return _("Unknown") else: return text_type(time.strftime("%c", time.localtime(t))) playcount = counter(song.get("~#playcount", 0)) skipcount = counter(song.get("~#skipcount", 0)) lastplayed = ftime(song.get("~#lastplayed", 0)) if lastplayed == _("Unknown"): lastplayed = _("Never") added = ftime(song.get("~#added", 0)) rating = song("~rating") has_rating = "~#rating" in song t = Table(5) table = [(_("added"), added, True), (_("last played"), lastplayed, True), (_("plays"), playcount, True), (_("skips"), skipcount, True), (_("rating"), rating, has_rating)] for i, (l, r, s) in enumerate(table): l = util.capitalize(l + ":") lab = Label(l) t.attach(lab, 0, 1, i + 1, i + 2, xoptions=Gtk.AttachOptions.FILL) label = Label(r) label.set_sensitive(s) t.attach(label, 1, 2, i + 1, i + 2) box.pack_start(Frame(_("Library"), t), False, False, 0)
def _additional(self, song, box): if "website" not in song and "comment" not in song: return data = [] if "comment" in song: comments = song.list("comment") markups = ["<i>%s</i>" % c for c in comments] data.append(("comment", markups)) if "website" in song: markups = [ "<a href=\"%(url)s\">%(text)s</a>" % { "text": util.escape(website), "url": util.escape(website) } for website in song.list("website") ] data.append(("website", markups)) table = Table(1) for i, (key, markups) in enumerate(data): title = readable(key, plural=len(markups) > 1) lab = Label(markup=util.capitalize(util.escape(title) + ":")) table.attach(lab, 0, 1, i, i + 1, xoptions=Gtk.AttachOptions.FILL) lab = Label(markup="\n".join(markups), ellipsize=True) table.attach(lab, 1, 2, i, i + 1) box.pack_start(Frame(_("Additional"), table), False, False, 0)
def _people(self, song, box): data = [] if "artist" in song: title = (_("artist") if len(song.list("artist")) == 1 else _("artists")) title = util.capitalize(title) data.append((title, song["artist"])) for tag_ in [ "performer", "lyricist", "arranger", "composer", "conductor", "author" ]: if tag_ in song: name = (tag(tag_) if len(song.list(tag_)) == 1 else readable( tag_, plural=True)) data.append((name, song[tag_])) performers = defaultdict(list) for tag_ in song: if "performer:" in tag_: for person in song.list(tag_): role = util.title(tag_.split(':', 1)[1]) performers[role].append(person) if performers: text = '\n'.join("%s (%s)" % (', '.join(names), part) for part, names in performers.iteritems()) name = (tag("performer") if len(performers) == 1 else _("performers")) data.append((name, text)) table = Table(len(data)) for i, (key, text) in enumerate(data): key = util.capitalize(util.escape(key) + ":") table.attach(Label(markup=key), 0, 1, i, i + 1, xoptions=Gtk.AttachOptions.FILL) label = Label(text, ellipsize=True) table.attach(label, 1, 2, i, i + 1) box.pack_start(Frame(tag("~people"), table), False, False, 0)
def _people(self, song, box): data = [] if "artist" in song: title = (_("artist") if len(song.list("artist")) == 1 else _("artists")) title = util.capitalize(title) data.append((title, song["artist"])) for tag_ in ["performer", "lyricist", "arranger", "composer", "conductor", "author"]: if tag_ in song: name = (tag(tag_) if len(song.list(tag_)) == 1 else readable(tag_, plural=True)) data.append((name, song[tag_])) performers = defaultdict(list) for tag_ in song: if "performer:" in tag_: for person in song.list(tag_): role = util.title(tag_.split(':', 1)[1]) performers[role].append(person) if performers: text = '\n'.join("%s (%s)" % (', '.join(names), part) for part, names in performers.iteritems()) name = (tag("performer") if len(performers) == 1 else _("performers")) data.append((name, text)) table = Table(len(data)) for i, (key, text) in enumerate(data): key = util.capitalize(util.escape(key) + ":") table.attach(Label(markup=key), 0, 1, i, i + 1, xoptions=Gtk.AttachOptions.FILL) label = Label(text, ellipsize=True) table.attach(label, 1, 2, i, i + 1) box.pack_start(Frame(tag("~people"), table), False, False, 0)
def _album(self, songs, box): albums = set([]) none = 0 for song in songs: if "album" in song: albums.update(song.list("album")) else: none += 1 albums = sorted(albums) num_albums = len(albums) if none: albums.append(ngettext("%d song with no album", "%d songs with no album", none) % none) box.pack_start(Frame( "%s (%d)" % (util.capitalize(_("albums")), num_albums), Label("\n".join(albums))), expand=False, fill=False)
def _album(self, songs, box): albums = set([]) none = 0 for song in songs: if "album" in song: albums.update(song.list("album")) else: none += 1 albums = sorted(albums) num_albums = len(albums) if none: albums.append( ngettext("%d song with no album", "%d songs with no album", none) % none) box.pack_start( Frame("%s (%d)" % (util.capitalize(_("albums")), num_albums), Label("\n".join(albums))), False, False, 0)
def _people(self, songs, box): artists = set() none = 0 for song in songs: if "artist" in song: artists.update(song.list("artist")) else: none += 1 artists = sorted(artists) num_artists = len(artists) if none: artists.append(ngettext("%d song with no artist", "%d songs with no artist", none) % none) box.pack_start(Frame( "%s (%d)" % (util.capitalize(_("artists")), num_artists), Label("\n".join(artists))), False, False, 0)
def _people(self, songs, box): artists = set() none = 0 for song in songs: if "artist" in song: artists.update(song.list("artist")) else: none += 1 artists = sorted(artists) num_artists = len(artists) if none: artists.append(ngettext("%d song with no artist", "%d songs with no artist", none) % none) label = Label(markup=util.escape("\n".join(artists)), ellipsize=True) frame = Frame("%s (%d)" % (util.capitalize(_("artists")), num_artists), label) box.pack_start(frame, False, False, 0)
def _library(self, song, box): def counter(i): if i == 0: return _("Never") else: return ngettext("%(n)d time", "%(n)d times", i) % {"n": i} def ftime(t): if t == 0: return _("Unknown") else: timestr = time.strftime("%c", time.localtime(t)) encoding = util.get_locale_encoding() return timestr.decode(encoding) playcount = counter(song.get("~#playcount", 0)) skipcount = counter(song.get("~#skipcount", 0)) lastplayed = ftime(song.get("~#lastplayed", 0)) if lastplayed == _("Unknown"): lastplayed = _("Never") added = ftime(song.get("~#added", 0)) rating = song("~rating") has_rating = "~#rating" in song t = Gtk.Table(n_rows=5, n_columns=2) t.set_col_spacings(6) t.set_homogeneous(False) table = [(_("added"), added, True), (_("last played"), lastplayed, True), (_("plays"), playcount, True), (_("skips"), skipcount, True), (_("rating"), rating, has_rating)] for i, (l, r, s) in enumerate(table): l = "<b>%s</b>" % util.capitalize(util.escape(l) + ":") lab = Label() lab.set_markup(l) t.attach(lab, 0, 1, i + 1, i + 2, xoptions=Gtk.AttachOptions.FILL) label = Label(r) label.set_sensitive(s) t.attach(label, 1, 2, i + 1, i + 2) box.pack_start(Frame(_("Library"), t), False, False, 0)
def _file(self, song, box): def ftime(t): if t == 0: return _("Unknown") else: timestr = time.strftime("%c", time.localtime(t)) encoding = util.get_locale_encoding() return timestr.decode(encoding) fn = fsdecode(unexpand(song["~filename"])) length = util.format_time_long(song.get("~#length", 0)) size = util.format_size( song.get("~#filesize") or filesize(song["~filename"])) mtime = ftime(util.path.mtime(song["~filename"])) format_ = song("~format") codec = song("~codec") encoding = song.comma("~encoding") bitrate = song("~bitrate") t = Gtk.Table(n_rows=4, n_columns=2) t.set_col_spacings(6) t.set_homogeneous(False) table = [(_("length"), length), (_("format"), format_), (_("codec"), codec), (_("encoding"), encoding), (_("bitrate"), bitrate), (_("file size"), size), (_("modified"), mtime)] fnlab = Label(fn) fnlab.set_ellipsize(Pango.EllipsizeMode.MIDDLE) t.attach(fnlab, 0, 2, 0, 1, xoptions=Gtk.AttachOptions.FILL) for i, (l, r) in enumerate(table): l = "<b>%s</b>" % util.capitalize(util.escape(l) + ":") lab = Label() lab.set_markup(l) t.attach(lab, 0, 1, i + 1, i + 2, xoptions=Gtk.AttachOptions.FILL) t.attach(Label(r), 1, 2, i + 1, i + 2) box.pack_start(Frame(_("File"), t), False, False, 0)
def _file(self, song, box): def ftime(t): if t == 0: return _("Unknown") else: timestr = time.strftime("%c", time.localtime(t)) encoding = util.get_locale_encoding() return timestr.decode(encoding) fn = fsn2text(unexpand(song["~filename"])) length = util.format_time_preferred(song.get("~#length", 0)) size = util.format_size( song.get("~#filesize") or filesize(song["~filename"])) mtime = ftime(util.path.mtime(song["~filename"])) format_ = song("~format") codec = song("~codec") encoding = song.comma("~encoding") bitrate = song("~bitrate") t = Gtk.Table(n_rows=4, n_columns=2) t.set_col_spacings(6) t.set_homogeneous(False) table = [(_("length"), length), (_("format"), format_), (_("codec"), codec), (_("encoding"), encoding), (_("bitrate"), bitrate), (_("file size"), size), (_("modified"), mtime)] fnlab = Label(fn) fnlab.set_ellipsize(Pango.EllipsizeMode.MIDDLE) t.attach(fnlab, 0, 2, 0, 1, xoptions=Gtk.AttachOptions.FILL) for i, (l, r) in enumerate(table): l = "<b>%s</b>" % util.capitalize(util.escape(l) + ":") lab = Label() lab.set_markup(l) t.attach(lab, 0, 1, i + 1, i + 2, xoptions=Gtk.AttachOptions.FILL) t.attach(Label(r), 1, 2, i + 1, i + 2) box.pack_start(Frame(_("File"), t), False, False, 0)
def _file(self, song, box): def ftime(t): if t == 0: return _("Unknown") else: timestr = time.strftime("%c", time.localtime(t)) if not PY3: timestr = timestr.decode(util.get_locale_encoding()) return timestr fn = fsn2text(unexpand(song["~filename"])) length = util.format_time_preferred(song.get("~#length", 0)) size = util.format_size( song.get("~#filesize") or filesize(song["~filename"])) mtime = ftime(util.path.mtime(song["~filename"])) format_ = song("~format") codec = song("~codec") encoding = song.comma("~encoding") bitrate = song("~bitrate") table = [(_("path"), fn), (_("length"), length), (_("format"), format_), (_("codec"), codec), (_("encoding"), encoding), (_("bitrate"), bitrate), (_("file size"), size), (_("modified"), mtime)] t = Table(len(table)) for i, (tag_, text) in enumerate(table): tag_ = util.capitalize(util.escape(tag_) + ":") lab = Label(text) lab.set_ellipsize(Pango.EllipsizeMode.MIDDLE) t.attach(Label(tag_), 0, 1, i, i + 1, xoptions=Gtk.AttachOptions.FILL) t.attach(lab, 1, 2, i, i + 1) box.pack_start(Frame(_("File"), t), False, False, 0)
def _library(self, song, box): def counter(i): return _("Never") if i == 0 \ else numeric_phrase("%(n)d time", "%(n)d times", i, "n") def ftime(t): if t == 0: return _("Unknown") else: timestr = time.strftime("%c", time.localtime(t)) if not PY3: timestr = timestr.decode(util.get_locale_encoding()) return timestr playcount = counter(song.get("~#playcount", 0)) skipcount = counter(song.get("~#skipcount", 0)) lastplayed = ftime(song.get("~#lastplayed", 0)) if lastplayed == _("Unknown"): lastplayed = _("Never") added = ftime(song.get("~#added", 0)) rating = song("~rating") has_rating = "~#rating" in song t = Table(5) table = [(_("added"), added, True), (_("last played"), lastplayed, True), (_("plays"), playcount, True), (_("skips"), skipcount, True), (_("rating"), rating, has_rating)] for i, (l, r, s) in enumerate(table): l = util.capitalize(l + ":") lab = Label(l) t.attach(lab, 0, 1, i + 1, i + 2, xoptions=Gtk.AttachOptions.FILL) label = Label(r) label.set_sensitive(s) t.attach(label, 1, 2, i + 1, i + 2) box.pack_start(Frame(_("Library"), t), False, False, 0)
def _album(self, songs, box): albums = set() none = 0 for song in songs: if "album" in song: albums.update(song.list("album")) else: none += 1 albums = sorted(albums) num_albums = len(albums) markup = "\n".join("<i>%s</i>" % util.escape(a) for a in albums) if none: text = ngettext("%d song with no album", "%d songs with no album", none) % none markup += "\n%s" % util.escape(text) label = Label() label.set_markup(markup) box.pack_start( Frame("%s (%d)" % (util.capitalize(_("albums")), num_albums), label), False, False, 0)
def _file(self, song, box): def ftime(t): if t == 0: return _("Unknown") else: timestr = time.strftime("%c", time.localtime(t)) return timestr.decode(const.ENCODING) fn = fsdecode(unexpand(song["~filename"])) length = util.format_time_long(song.get("~#length", 0)) size = util.format_size( song.get("~#filesize") or filesize(song["~filename"])) mtime = ftime(util.path.mtime(song["~filename"])) bitrate = song.get("~#bitrate", 0) if bitrate != 0: bitrate = _("%d kbps") % int(bitrate) else: bitrate = False t = Gtk.Table(n_rows=4, n_columns=2) t.set_col_spacings(6) t.set_homogeneous(False) table = [(_("length"), length), (_("file size"), size), (_("modified"), mtime)] if bitrate: table.insert(1, (_("bitrate"), bitrate)) fnlab = Label(fn) fnlab.set_ellipsize(Pango.EllipsizeMode.MIDDLE) t.attach(fnlab, 0, 2, 0, 1, xoptions=Gtk.AttachOptions.FILL) for i, (l, r) in enumerate(table): l = "<b>%s</b>" % util.capitalize(util.escape(l) + ":") lab = Label() lab.set_markup(l) t.attach(lab, 0, 1, i + 1, i + 2, xoptions=Gtk.AttachOptions.FILL) t.attach(Label(r), 1, 2, i + 1, i + 2) box.pack_start(Frame(_("File"), t), False, False, 0)
def _album(self, songs, box): albums = set() none = 0 for song in songs: if "album" in song: albums.update(song.list("album")) else: none += 1 albums = sorted(albums) num_albums = len(albums) markup = "\n".join("<i>%s</i>" % util.escape(a) for a in albums) if none: text = ngettext("%d song with no album", "%d songs with no album", none) % none markup += "\n%s" % util.escape(text) label = Label() label.set_markup(markup) box.pack_start(Frame( "%s (%d)" % (util.capitalize(_("albums")), num_albums), label), False, False, 0)
def _file(self, song, box): def ftime(t): if t == 0: return _("Unknown") else: return text_type(time.strftime("%c", time.localtime(t))) fn = fsn2text(unexpand(song["~filename"])) length = util.format_time_preferred(song.get("~#length", 0)) size = util.format_size( song.get("~#filesize") or filesize(song["~filename"])) mtime = ftime(util.path.mtime(song["~filename"])) format_ = song("~format") codec = song("~codec") encoding = song.comma("~encoding") bitrate = song("~bitrate") table = [(_("path"), fn), (_("length"), length), (_("format"), format_), (_("codec"), codec), (_("encoding"), encoding), (_("bitrate"), bitrate), (_("file size"), size), (_("modified"), mtime)] t = Table(len(table)) for i, (tag_, text) in enumerate(table): tag_ = util.capitalize(util.escape(tag_) + ":") lab = Label(text) lab.set_ellipsize(Pango.EllipsizeMode.MIDDLE) t.attach(Label(tag_), 0, 1, i, i + 1, xoptions=Gtk.AttachOptions.FILL) t.attach(lab, 1, 2, i, i + 1) box.pack_start(Frame(_("File"), t), False, False, 0)
def _library(self, song, box): def counter(i): if i == 0: return _("Never") else: return ngettext("%(n)d time", "%(n)d times", i) % {"n": i} def ftime(t): if t == 0: return _("Unknown") else: timestr = time.strftime("%c", time.localtime(t)) return timestr.decode(const.ENCODING) playcount = counter(song.get("~#playcount", 0)) skipcount = counter(song.get("~#skipcount", 0)) lastplayed = ftime(song.get("~#lastplayed", 0)) if lastplayed == _("Unknown"): lastplayed = _("Never") added = ftime(song.get("~#added", 0)) rating = song("~rating") t = gtk.Table(5, 2) t.set_col_spacings(6) t.set_homogeneous(False) table = [(_("added"), added), (_("last played"), lastplayed), (_("plays"), playcount), (_("skips"), skipcount), (_("rating"), rating)] for i, (l, r) in enumerate(table): l = "<b>%s</b>" % util.capitalize(util.escape(l) + ":") lab = Label() lab.set_markup(l) t.attach(lab, 0, 1, i + 1, i + 2, xoptions=gtk.FILL) t.attach(Label(r), 1, 2, i + 1, i + 2) box.pack_start(Frame(_("Library"), t), expand=False, fill=False)
def test_preserve(self): self.failUnlessEqual(util.capitalize("aa B"), "Aa B")
def test_empty(self): self.failUnlessEqual(util.capitalize(""), "")
def __create_menu(self, player, library): ag = Gtk.ActionGroup.new('QuodLibetWindowActions') def logging_cb(*args): window = LoggingWindow(self) window.show() actions = [ ('Music', None, _("_Music")), ('AddFolders', Gtk.STOCK_ADD, _('_Add a Folder...'), "<control>O", None, self.open_chooser), ('AddFiles', Gtk.STOCK_ADD, _('_Add a File...'), None, None, self.open_chooser), ('AddLocation', Gtk.STOCK_ADD, _('_Add a Location...'), None, None, self.open_location), ('BrowseLibrary', Gtk.STOCK_FIND, _('Open _Browser'), ""), ("Preferences", Gtk.STOCK_PREFERENCES, None, None, None, self.__preferences), ("Plugins", Gtk.STOCK_EXECUTE, _("_Plugins"), None, None, self.__plugins), ("Quit", Gtk.STOCK_QUIT, None, None, None, self.destroy), ('Filters', None, _("_Filters")), ("PlayedRecently", Gtk.STOCK_FIND, _("Recently _Played"), "", None, self.__filter_menu_actions), ("AddedRecently", Gtk.STOCK_FIND, _("Recently _Added"), "", None, self.__filter_menu_actions), ("TopRated", Gtk.STOCK_FIND, _("_Top 40"), "", None, self.__filter_menu_actions), ("All", Gtk.STOCK_FIND, _("All _Songs"), "", None, self.__filter_menu_actions), ("Control", None, _("_Control")), ("EditTags", Gtk.STOCK_PROPERTIES, _("Edit _Tags"), "", None, self.__current_song_prop), ("Information", Gtk.STOCK_INFO, None, None, None, self.__current_song_info), ("Jump", Gtk.STOCK_JUMP_TO, _("_Jump to Playing Song"), "<control>J", None, self.__jump_to_current), ("View", None, _("_View")), ("Help", None, _("_Help")), ("OutputLog", Gtk.STOCK_EDIT, _("_Output Log"), None, None, logging_cb), ] actions.append(("Previous", Gtk.STOCK_MEDIA_PREVIOUS, None, "<control>comma", None, self.__previous_song)) actions.append(("PlayPause", Gtk.STOCK_MEDIA_PLAY, None, "<control>space", None, self.__play_pause)) actions.append(("Next", Gtk.STOCK_MEDIA_NEXT, None, "<control>period", None, self.__next_song)) ag.add_actions(actions) act = Gtk.ToggleAction.new("StopAfter", _("Stop After This Song"), None, "") ag.add_action_with_accel(act, "<shift>space") # access point for the tray icon self.stop_after = act act = Gtk.Action.new( "AddBookmark", _("Add Bookmark"), None, Gtk.STOCK_ADD) act.connect_object('activate', self.__add_bookmark, library.librarian, player) ag.add_action_with_accel(act, "<ctrl>D") act = Gtk.Action.new("EditBookmarks", _(u"Edit Bookmarks…"), None, "") act.connect_object('activate', self.__edit_bookmarks, library.librarian, player) ag.add_action_with_accel(act, "<ctrl>B") act = Gtk.Action.new("About", None, None, Gtk.STOCK_ABOUT) act.connect_object('activate', self.__show_about, player) ag.add_action_with_accel(act, None) act = Gtk.Action.new( "OnlineHelp", _("Online Help"), None, Gtk.STOCK_HELP) act.connect_object('activate', util.website, const.ONLINE_HELP) ag.add_action_with_accel(act, "F1") act = Gtk.Action.new("SearchHelp", _("Search Help"), None, "") act.connect_object('activate', util.website, const.SEARCH_HELP) ag.add_action_with_accel(act, None) act = Gtk.Action.new( "RefreshLibrary", _("Re_fresh Library"), None, Gtk.STOCK_REFRESH) act.connect('activate', self.__rebuild, False) ag.add_action_with_accel(act, None) for tag_, lab in [ ("genre", _("Filter on _Genre")), ("artist", _("Filter on _Artist")), ("album", _("Filter on Al_bum"))]: act = Gtk.Action.new( "Filter%s" % util.capitalize(tag_), lab, None, Gtk.STOCK_INDEX) act.connect_object('activate', self.__filter_on, tag_, None, player) ag.add_action_with_accel(act, None) for (tag_, accel, label) in [ ("genre", "G", _("Random _Genre")), ("artist", "T", _("Random _Artist")), ("album", "M", _("Random Al_bum"))]: act = Gtk.Action.new("Random%s" % util.capitalize(tag_), label, None, Gtk.STOCK_DIALOG_QUESTION) act.connect('activate', self.__random, tag_) ag.add_action_with_accel(act, "<control>" + accel) ag.add_toggle_actions([ ("SongList", None, _("Song _List"), None, None, self.showhide_playlist, config.getboolean("memory", "songlist"))]) ag.add_toggle_actions([ ("Queue", None, _("_Queue"), None, None, self.showhide_playqueue, config.getboolean("memory", "queue"))]) view_actions = [] for i, Kind in enumerate(browsers.browsers): action = "View" + Kind.__name__ label = Kind.accelerated_name view_actions.append((action, None, label, None, None, i)) current = browsers.index(config.get("memory", "browser")) def action_callback(view_action, current): self.select_browser(view_action, current, library, player) ag.add_radio_actions( view_actions, current, action_callback, None) for Kind in browsers.browsers: if not Kind.in_menu: continue action = "Browser" + Kind.__name__ label = Kind.accelerated_name act = Gtk.Action.new(action, label, None, None) act.connect_object('activate', LibraryBrowser.open, Kind, library) ag.add_action_with_accel(act, None) debug_menu = "" if const.DEBUG: debug_menu = ( "<separator/>" "<menuitem action='OutputLog' always-show-image='true'/>") ui = Gtk.UIManager() ui.insert_action_group(ag, -1) menustr = const.MENU % {"browsers": browsers.BrowseLibrary(), "views": browsers.ViewBrowser(), "debug": debug_menu} ui.add_ui_from_string(menustr) # Cute. So. UIManager lets you attach tooltips, but when they're # for menu items, they just get ignored. So here I get to actually # attach them. ui.get_widget("/Menu/Music/RefreshLibrary").set_tooltip_text( _("Check for changes in your library")) ui.get_widget("/Menu/Filters/TopRated").set_tooltip_text( _("The 40 songs you've played most (more than 40 may " "be chosen if there are ties)")) return ui
def __create_menu(self, player, library): ag = gtk.ActionGroup('QuodLibetWindowActions') actions = [ ('Music', None, _("_Music")), ('SwitchAudioOutputs', gtk.STOCK_FIND, _('_Audio Outputs'), ""), ('BrowseLibrary', gtk.STOCK_FIND, _('_Browse Library'), ""), ("Preferences", gtk.STOCK_PREFERENCES, None, None, None, self.__preferences), ("Quit", gtk.STOCK_QUIT, None, None, None, self.destroy), ('Filters', None, _("_Filters")), ("PlayedRecently", gtk.STOCK_FIND, _("Recently _Played"), "", None, self.__filter_menu_actions), ("AddedRecently", gtk.STOCK_FIND, _("Recently _Added"), "", None, self.__filter_menu_actions), ("TopRated", gtk.STOCK_FIND, _("_Top 40"), "", None, self.__filter_menu_actions), ("Control", None, _("_Control")), ("EditTags", gtk.STOCK_PROPERTIES, _("Edit _Tags"), "", None, self.__current_song_prop), ("Information", gtk.STOCK_INFO, None, None, None, self.__current_song_info), ("Jump", gtk.STOCK_JUMP_TO, _("_Jump to Playing Song"), "<control>J", None, self.__jump_to_current), ("View", None, _("_View")), ("Help", None, _("_Help")), ("OutputLog", gtk.STOCK_EDIT, _("_Output Log"), None, None, lambda *args: LoggingWindow(self)), ] if const.DEBUG: from quodlibet.debug import cause_error, enc actions.append(("DebugReload", gtk.STOCK_DIALOG_WARNING, _("_Edit and Continue"), None, None, lambda *args: enc.reload())) actions.append(("DebugCauseError", gtk.STOCK_DIALOG_ERROR, _("_Cause an Error"), None, None, cause_error)) actions.append(("Previous", gtk.STOCK_MEDIA_PREVIOUS, None, "<control>comma", None, self.__previous_song)) actions.append(("PlayPause", gtk.STOCK_MEDIA_PLAY, None, "<control>space", None, self.__play_pause)) actions.append(("Next", gtk.STOCK_MEDIA_NEXT, None, "<control>period", None, self.__next_song)) ag.add_actions(actions) act = gtk.Action("About", None, None, gtk.STOCK_ABOUT) act.connect_object('activate', self.__show_about, player) ag.add_action_with_accel(act, None) act = gtk.Action("OnlineHelp", _("Online Help"), None, gtk.STOCK_HELP) act.connect_object('activate', util.website, const.ONLINE_HELP) ag.add_action_with_accel(act, "F1") act = gtk.Action("SearchHelp", _("Search Help"), None, "") act.connect_object('activate', util.website, const.SEARCH_HELP) ag.add_action_with_accel(act, None) act = gtk.Action( "RefreshLibrary", _("Re_fresh Library"), None, gtk.STOCK_REFRESH) act.connect('activate', self.__rebuild, False) ag.add_action_with_accel(act, None) act = gtk.Action( "ConnectDisconnect", _("_Connect/Disconnect"), None, gtk.STOCK_REFRESH) act.connect('activate', self.__toggle_connected, True) ag.add_action_with_accel(act, None) for tag_, lab in [ ("genre", _("Filter on _Genre")), ("artist", _("Filter on _Artist")), ("album", _("Filter on Al_bum"))]: act = gtk.Action( "Filter%s" % util.capitalize(tag_), lab, None, gtk.STOCK_INDEX) act.connect_object('activate', self.__filter_on, tag_, None, player) ag.add_action_with_accel(act, None) for (tag_, accel, label) in [ ("genre", "G", _("Random _Genre")), ("artist", "T", _("Random _Artist")), ("album", "M", _("Random Al_bum"))]: act = gtk.Action("Random%s" % util.capitalize(tag_), label, None, gtk.STOCK_DIALOG_QUESTION) act.connect('activate', self.__random, tag_) ag.add_action_with_accel(act, "<control>" + accel) ag.add_toggle_actions([ ("SongList", None, _("Song _List"), None, None, self.showhide_playlist, config.getboolean("memory", "songlist"))]) ag.add_toggle_actions([ ("Queue", None, _("_Queue"), None, None, self.showhide_playqueue, config.getboolean("memory", "queue"))]) view_actions = [] for i, Kind in enumerate(browsers.browsers): action = "View" + Kind.__name__ label = Kind.accelerated_name view_actions.append((action, None, label, None, None, i)) current = browsers.index(config.get("memory", "browser")) ag.add_radio_actions( view_actions, current, self.select_browser, (library, player)) for Kind in browsers.browsers: if not Kind.in_menu: continue action = "Browser" + Kind.__name__ label = Kind.accelerated_name act = gtk.Action(action, label, None, None) act.connect_object('activate', LibraryBrowser, Kind, library) ag.add_action_with_accel(act, None) debug_menu = "" if const.DEBUG: debug_menu = ("<separator/>" "<menuitem action='OutputLog'/>" "<menuitem action='DebugReload'/>" "<menuitem action='DebugCauseError'/>") self.ui = gtk.UIManager() self.ui.insert_action_group(ag, -1) menustr = const.MENU % {"browsers": browsers.BrowseLibrary(), "views": browsers.ViewBrowser(), "mpd_audio_outputs": self._mpd.browse_audio_outputs(), "debug": debug_menu} self.ui.add_ui_from_string(menustr) # Cute. So. UIManager lets you attach tooltips, but when they're # for menu items, they just get ignored. So here I get to actually # attach them. self.ui.get_widget("/Menu/Music/RefreshLibrary").set_tooltip_text( _("Check for changes in your library")) self.ui.get_widget("/Menu/Filters/TopRated").set_tooltip_text( _("The 40 songs you've played most (more than 40 may " "be chosen if there are ties)"))
def test_nonalphabet(self): self.failUnlessEqual(util.capitalize("!aa B"), "!aa B")
def test_firstword(self): self.failUnlessEqual(util.capitalize("aa b"), "Aa b")
def get_field_name(field, key): field_name = (field.human_name or (key and key.replace("_", " "))) return field_name and util.capitalize(field_name) or _("(unknown)")