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 get(self, key, default="", connector=" - "): if key[:1] == "~" and '~' in key[1:]: return connector.join(map(self.get, util.tagsplit(key))) elif key[:1] == "~" and key[-4:-3] == ":": func = key[-3:] key = key[:-4] return "%s<%s>" % (util.tag(key), func) elif key in self: return self[key] return util.tag(key)
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 _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 _album(self, song, box): if "album" not in song: return text = ["<span size='x-large'><i>%s</i></span>" % util.escape(song.comma("album"))] secondary = [] if "discnumber" in song: secondary.append(_("Disc %s") % song["discnumber"]) if "discsubtitle" in song: secondary.append("<i>%s</i>" % util.escape(song.comma("discsubtitle"))) if "tracknumber" in song: secondary.append(_("Track %s") % song["tracknumber"]) if secondary: text.append(" - ".join(secondary)) if "date" in song: text.append(util.escape(song.comma("date"))) if "organization" in song or "labelid" in song: t = util.escape(song.comma("~organization~labelid")) text.append(t) if "producer" in song: text.append(_("Produced by %s") % ( util.escape(song.comma("producer")))) w = Label(markup="\n".join(text), ellipsize=True) hb = Gtk.HBox(spacing=12) hb.pack_start(w, True, True, 0) box.pack_start(Frame(tag("album"), hb), False, False, 0) cover = ReactiveCoverImage(song=song) hb.pack_start(cover, False, True, 0)
def Filter(t): # Translators: The substituted string is the name of the # selected column (a translated tag name). b = qltk.MenuItem( _("_Filter on %s") % util.tag(t, True), Gtk.STOCK_INDEX) b.connect('activate', self.__filter_on, t, songs, browser) return b
def _execute(self, options, args): if len(args) < 1: raise CommandError(_("Not enough arguments")) elif len(args) > 1: raise CommandError(_("Too many arguments")) path = args[0] song = self.load_song(path) headers = [_("Description"), _("Value")] nicks = ["desc", "value"] if not options.columns: order = nicks else: order = [n.strip() for n in options.columns.split(",")] if not options.terse: tags = [] for key in ["~format", "~codec", "~encoding", "~length", "~bitrate", "~filesize"]: tags.append((util.tag(key), text_type(song.comma(key)))) print_table(tags, headers, nicks, order) else: tags = [] for key in ["~format", "~codec", "~encoding", "~#length", "~#bitrate", "~#filesize"]: tags.append((key.lstrip("#~"), text_type(song(key)))) print_terse_table(tags, nicks, order)
def _album(self, song, box): if "album" not in song: return w = Label("") text = [] text.append("<i>%s</i>" % util.escape(song.comma("album"))) if "date" in song: text[-1] += " (%s)" % util.escape(song.comma("date")) secondary = [] if "discnumber" in song: secondary.append(_("Disc %s") % song["discnumber"]) if "discsubtitle" in song: secondary.append("<i>%s</i>" % util.escape(song.comma("discsubtitle"))) if "tracknumber" in song: secondary.append(_("Track %s") % song["tracknumber"]) if secondary: text.append(" - ".join(secondary)) if "organization" in song or "labelid" in song: t = util.escape(song.comma("~organization~labelid")) text.append(t) if "producer" in song: text.append("Produced by %s" %( util.escape(song.comma("producer")))) w.set_markup("\n".join(text)) w.set_ellipsize(pango.ELLIPSIZE_END) hb = gtk.HBox(spacing=12) cover = CoverImage(song=song) if cover: hb.pack_start(cover, expand=False) else: cover.destroy() hb.pack_start(w) box.pack_start(Frame(tag("album"), hb), expand=False, fill=False)
def Filter(t): # Translators: The substituted string is the name of the # selected column (a translated tag name). b = qltk.MenuItem( _("_Filter on %s") % util.tag(t, True), Icons.EDIT_FIND) b.connect('activate', self.__filter_on, t, songs, browser) return b
def _execute(self, options, args): if len(args) != 0: raise CommandError(_("Too many arguments")) headers = [_("Tag"), _("Description")] nicks = ["tag", "desc"] if not options.columns: order = nicks else: order = [n.strip() for n in options.columns.split(",")] tag_names = list(USER_TAGS) if options.all: tag_names.extend(MACHINE_TAGS) tags = [] for key in tag_names: tags.append((key, util.tag(key))) tags.sort() if not options.terse: print_table(tags, headers, nicks, order) else: print_terse_table(tags, nicks, order)
def _execute(self, options, args): if len(args) < 1: raise CommandError(_("Not enough arguments")) elif len(args) > 1: raise CommandError(_("Too many arguments")) path = args[0] song = self.load_song(path) headers = [_("Description"), _("Value")] nicks = ["desc", "value"] if not options.columns: order = nicks else: order = [n.strip() for n in options.columns.split(",")] if not options.terse: tags = [] for key in [ "~format", "~codec", "~encoding", "~length", "~bitrate", "~filesize" ]: tags.append((util.tag(key), str(song.comma(key)))) print_table(tags, headers, nicks, order) else: tags = [] for key in [ "~format", "~codec", "~encoding", "~#length", "~#bitrate", "~#filesize" ]: tags.append((key.lstrip("#~"), str(song(key)))) print_terse_table(tags, nicks, order)
def __init__(self, activator): super(Preferences, self).__init__(spacing=12) self.set_border_width(6) combo = Gtk.ComboBoxText() combo.append_text( _("Scroll wheel adjusts volume\n" "Shift and scroll wheel changes song")) combo.append_text( _("Scroll wheel changes song\n" "Shift and scroll wheel adjusts volume")) combo.set_active( int(config.getboolean("plugins", "icon_modifier_swap", False))) combo.connect('changed', self.__changed_combo) self.pack_start(qltk.Frame(_("Scroll _Wheel"), child=combo), True, True, 0) box = Gtk.VBox(spacing=12) table = Gtk.Table(2, 4) table.set_row_spacings(6) table.set_col_spacings(12) cbs = [] for i, tag in enumerate([ "genre", "artist", "album", "discnumber", "part", "tracknumber", "title", "version" ]): cb = Gtk.CheckButton(util.tag(tag)) cb.tag = tag cbs.append(cb) table.attach(cb, i % 3, i % 3 + 1, i // 3, i // 3 + 1) box.pack_start(table, True, True, 0) entry = Gtk.Entry() box.pack_start(entry, False, True, 0) preview = Gtk.Label() preview.set_ellipsize(Pango.EllipsizeMode.END) ev = Gtk.EventBox() ev.add(preview) box.pack_start(ev, False, True, 0) frame = qltk.Frame(_("Tooltip Display"), child=box) frame.get_label_widget().set_mnemonic_widget(entry) self.pack_start(frame, True, True, 0) for cb in cbs: cb.connect('toggled', self.__changed_cb, cbs, entry) entry.connect('changed', self.__changed_entry, cbs, preview) try: entry.set_text(config.get("plugins", "icon_tooltip")) except: entry.set_text( "<album|<album~discnumber~part~tracknumber~title~version>|" "<artist~title~version>>") for child in self.get_children(): child.show_all()
def __init__(self, row_pattern): parts = [p.replace(r"\:", ":") for p in (re.split(r"(?<!\\):", row_pattern))] is_numeric = lambda s: s[:2] == "~#" and "~" not in s[2:] is_pattern = lambda s: '<' in s f_round = lambda s: (isinstance(s, float) and "%.2f" % s) or s def is_date(s): return s in TIME_TAGS disp = parts[1] if len( parts) >= 2 else r"[i][span alpha='40%']<~#tracks>[/span][/i]" cat = parts[0] if is_pattern(cat): title = util.pattern(cat, esc=True, markup=True) try: pc = XMLFromPattern(cat) except ValueError: pc = XMLFromPattern("") tags = pc.tags format = pc.format_list has_markup = True else: title = util.tag(cat) tags = util.tagsplit(cat) has_markup = False if is_date(cat): def format(song: AudioFile) -> List[Tuple[Text, Text]]: fmt = config.gettext("settings", "datecolumn_timestamp_format") date_str = format_date(song(cat), fmt) return [(date_str, date_str)] elif is_numeric(cat): def format(song: AudioFile) -> List[Tuple[Text, Text]]: v = str(f_round(song(cat))) return [(v, v)] else: def format(song: AudioFile) -> List[Tuple[Text, Text]]: return song.list_separate(cat) if is_pattern(disp): try: pd = XMLFromPattern(disp) except ValueError: pd = XMLFromPattern("") format_display = pd.format else: if is_numeric(disp): format_display = lambda coll: str(f_round(coll(disp))) else: format_display = lambda coll: util.escape(coll.comma(disp)) self.title = title self.tags = set(tags) self.format = format self.format_display = format_display self.has_markup = has_markup
class Preferences(qltk.UniqueWindow, EditDisplayPatternMixin): _A_SIZE = 127 * 1024 * 1024 _SOME_PEOPLE = "\n".join( tag(t) for t in ["artist", "performer", "composer", "arranger"]) _DEFAULT_PATTERN = DEFAULT_PATTERN_TEXT _PREVIEW_ITEM = FakeDisplayItem({ "date": "2015-11-31", "~length": format_time_display(6319), "~long-length": format_time_long(6319), "~tracks": numeric_phrase("%d track", "%d tracks", 27), "~#filesize": _A_SIZE, "~filesize": format_size(_A_SIZE), "~#rating": 0.75, "~name": _("Example Playlist"), "~people": _SOME_PEOPLE + "..." }) def __init__(self, browser): if self.is_not_unique(): return super(Preferences, self).__init__() self.set_border_width(12) self.set_title(_("Playlist Browser Preferences")) self.set_default_size(420, 240) self.set_transient_for(qltk.get_top_parent(browser)) box = Gtk.VBox(spacing=6) edit_frame = self.edit_display_pane(browser, _("Playlist display")) box.pack_start(edit_frame, False, True, 12) main_box = Gtk.VBox(spacing=12) close = Button(_("_Close"), Icons.WINDOW_CLOSE) close.connect('clicked', lambda *x: self.destroy()) b = Gtk.HButtonBox() b.set_layout(Gtk.ButtonBoxStyle.END) b.pack_start(close, True, True, 0) main_box.pack_start(box, True, True, 0) self.use_header_bar() if not self.has_close_button(): main_box.pack_start(b, False, True, 0) self.add(main_box) close.grab_focus() self.show_all()
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 __preview_pattern(self, edit, label): people = "\n".join( [util.tag("artist"), util.tag("performer"), util.tag("arranger")]) album = FakeAlbum({"date": "2004-10-31", "~length": util.format_time(6319), "~long-length": util.format_time_long(6319), "~tracks": ngettext("%d track", "%d tracks", 5) % 5, "~discs": ngettext("%d disc", "%d discs", 2) % 2, "~people": people}) try: text = XMLFromPattern(edit.text) % album except: text = _("Invalid pattern") edit.apply.set_sensitive(False) try: pango.parse_markup(text, u"\u0000") except gobject.GError: text = _("Invalid pattern") edit.apply.set_sensitive(False) else: edit.apply.set_sensitive(True) label.set_markup(text)
def __init__(self, t): self._render = gtk.CellRendererText() title = util.tag(t) super(SongList.TextColumn, self).__init__(title, self._render) self.header_name = t self.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) self.set_visible(True) self.set_clickable(True) self.set_sort_indicator(False) self.set_cell_data_func(self._render, self._cdf, t) self._text = set() self._timeout = None self._update_layout(title, force=True)
def update_submenu(self): submenu = Gtk.Menu() tags = config.getlist("plugins", "wiki_tags", self.DEFAULT_TAGS) for tag in tags: if tag: item = Gtk.MenuItem(label=util.tag(tag)) item.connect('activate', self._set_selected_tag, tag) submenu.append(item) if submenu.get_children(): self.set_submenu(submenu) else: self.set_sensitive(False)
def __init__(self): super(SortCriterionBox, self).__init__(gtk.TreeStore(str, str)) render = gtk.CellRendererText() self.pack_start(render, True) self.add_attribute(render, 'text', 1) model = self.get_model() for (group, items) in self.__criterions: group_row = model.append(None, row=[group, group]) for t in items: model.append(group_row, row=[t, "%s (%s)" % (tag(t), t)]) self.set_active(0)
def __init__(self): super(SortCriterionBox, self).__init__(model=Gtk.TreeStore(str, str)) render = Gtk.CellRendererText() self.pack_start(render, True) self.add_attribute(render, 'text', 1) model = self.get_model() for (group, items) in self.__criterions: group_row = model.append(None, row=[group, group]) for t in items: model.append(group_row, row=[t, "%s (%s)" % (tag(t), t)]) self.set_active(0)
def __init__(self, row_pattern): parts = re.split(r"(?<!\\):", row_pattern) parts = list(map(lambda p: p.replace(r"\:", ":"), parts)) is_numeric = lambda s: s[:2] == "~#" and "~" not in s[2:] is_pattern = lambda s: '<' in s f_round = lambda s: (isinstance(s, float) and "%.2f" % s) or s disp = (len(parts) >= 2 and parts[1]) or r"[i](<~#tracks>)[/i]" cat = parts[0] if is_pattern(cat): title = util.pattern(cat, esc=True, markup=True) try: pc = XMLFromPattern(cat) except ValueError: pc = XMLFromPattern("") tags = pc.tags format = pc.format_list has_markup = True else: title = util.tag(cat) tags = util.tagsplit(cat) has_markup = False if is_numeric(cat): def format(song): v = text_type(f_round(song(cat))) return [(v, v)] else: format = lambda song: song.list_separate(cat) if is_pattern(disp): try: pd = XMLFromPattern(disp) except ValueError: pd = XMLFromPattern("") format_display = pd.format else: if is_numeric(disp): format_display = lambda coll: text_type(f_round(coll(disp))) else: format_display = lambda coll: util.escape(coll.comma(disp)) self.title = title self.tags = set(tags) self.format = format self.format_display = format_display self.has_markup = has_markup
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 get_markup(self, tags, iter_): obj = self.get_value(iter_, 0) if isinstance(obj, AlbumNode): return PAT % obj.album if isinstance(obj, string_types): markup = util.escape(obj) else: tag = util.tag(tags[len(self.get_path(iter_).get_indices()) - 1]) if obj is UnknownNode: markup = UNKNOWN_PATTERN % util.escape(tag) else: markup = MULTI_PATTERN % util.escape(tag) num = len(self.get_albums_for_iter(iter_)) return markup + COUNT_PATTERN % num
def get_markup(self, tags, iter_): obj = self[iter_][0] if isinstance(obj, Album): return PAT % obj if isinstance(obj, basestring): markup = util.escape(obj) else: tag = util.tag(tags[len(self.get_path(iter_)) - 1]) if obj is UnknownNode: markup = UNKNOWN_PATTERN % util.escape(tag) else: markup = MULTI_PATTERN % util.escape(tag) num = len(StoreUtils.get_albums_for_iter(self, iter_)) return markup + COUNT_PATTERN % num
def to_html(songs): cols = get_columns() cols_s = "" for col in cols: cols_s += '<th>%s</th>' % tag(col) songs_s = "" for song in songs: s = '<tr>' for col in cols: col = {"~#rating": "~rating", "~#length": "~length"}.get(col, col) s += '\n<td>%s</td>' % (escape(str(song.comma(col))) or ' ') s += '</tr>' songs_s += s return HTML % {'headers': cols_s, 'songs': songs_s}
def _fill_model(self, can_change): self.clear() render = Gtk.CellRendererText() self.pack_start(render, True) self.add_attribute(render, 'text', 1) if can_change is None: can_change = self.__tags can_change = sorted(can_change) model = self.get_model() for t in can_change: model.append(row=[t, "%s (%s)" % (tag(t), t)]) self.set_model(model) if len(model) == 0: raise ValueError("TagsCombo boxes require at least one tag name")
def _album(self, song, box): if "album" not in song: return w = Label("") text = [] text.append("<i>%s</i>" % util.escape(song.comma("album"))) if "date" in song: text[-1] += " (%s)" % util.escape(song.comma("date")) secondary = [] if "discnumber" in song: secondary.append(_("Disc %s") % song["discnumber"]) if "discsubtitle" in song: secondary.append("<i>%s</i>" % util.escape(song.comma("discsubtitle"))) if "tracknumber" in song: secondary.append(_("Track %s") % song["tracknumber"]) if secondary: text.append(" - ".join(secondary)) if "organization" in song or "labelid" in song: t = util.escape(song.comma("~organization~labelid")) text.append(t) if "producer" in song: text.append("Produced by %s" % (util.escape(song.comma("producer")))) w.set_markup("\n".join(text)) w.set_ellipsize(Pango.EllipsizeMode.END) hb = Gtk.HBox(spacing=12) cover = CoverImage() cover.set_property('no-show-all', True) hb.pack_start(cover, False, True, 0) def show_cover(cover, success): if success: cover.show() cover.disconnect(signal_id) signal_id = cover.connect('cover-visible', show_cover) cover.set_song(song) hb.pack_start(w, True, True, 0) box.pack_start(Frame(tag("album"), hb), False, False, 0)
def _album(self, song, box): if "album" not in song: return w = Label("") text = [] text.append("<i>%s</i>" % util.escape(song.comma("album"))) if "date" in song: text[-1] += " (%s)" % util.escape(song.comma("date")) secondary = [] if "discnumber" in song: secondary.append(_("Disc %s") % song["discnumber"]) if "discsubtitle" in song: secondary.append("<i>%s</i>" % util.escape(song.comma("discsubtitle"))) if "tracknumber" in song: secondary.append(_("Track %s") % song["tracknumber"]) if secondary: text.append(" - ".join(secondary)) if "organization" in song or "labelid" in song: t = util.escape(song.comma("~organization~labelid")) text.append(t) if "producer" in song: text.append("Produced by %s" % ( util.escape(song.comma("producer")))) w.set_markup("\n".join(text)) w.set_ellipsize(Pango.EllipsizeMode.END) hb = Gtk.HBox(spacing=12) cover = CoverImage() cover.set_property('no-show-all', True) hb.pack_start(cover, False, True, 0) def show_cover(cover, success): if success: cover.show() cover.disconnect(signal_id) signal_id = cover.connect('cover-visible', show_cover) cover.set_song(song) hb.pack_start(w, True, True, 0) box.pack_start(Frame(tag("album"), hb), False, False, 0)
def to_html(songs): cols = get_columns() cols_s = "" for col in cols: cols_s += '<th>%s</th>' % tag(col) songs_s = "" for song in songs: s = '<tr>' for col in cols: col = {"~#rating": "~rating", "~#length": "~length"}.get( col, col) s += '\n<td>%s</td>' % ( escape(text_type(song.comma(col))) or ' ') s += '</tr>' songs_s += s return HTML % {'headers': cols_s, 'songs': songs_s}
def list_tags(song, machine=False, terse=False): """Return a list of key, value pairs""" keys = set(song.realkeys()) if not machine: keys.difference_update(MACHINE_TAGS) tags = [] for key in sorted(keys, key=sortkey): for value in song.list(key): if not terse: # QL can't handle multiline values and splits them by \n. # Tags with Windows line endings leave a \r, messing up the # table layout value = value.rstrip("\r") # Normalize tab value = value.replace("\t", " ") tags.append((util.tag(key), value, key)) return tags
def _execute(self, options, args): if len(args) != 0: raise CommandError(_("Too many arguments")) headers = [_("Tag"), _("Description")] nicks = ["tag", "desc"] if not options.columns: order = nicks else: order = map(str.strip, options.columns.split(",")) tags = [] for key in USER_TAGS: tags.append((key, util.tag(key))) tags.sort() if not options.terse: print_table(tags, headers, nicks, order) else: print_terse_table(tags, nicks, order)
def test_precap_handling(self): self.failUnlessEqual(util.tag("labelid"), "Label ID") self.failUnlessEqual(util.tag("labelid", False), "label ID")
def test_two_nocap(self): self.failUnlessEqual(util.tag("title~version", False), "title / version")
def test_two(self): self.failUnlessEqual(util.tag("title~version"), "Title / Version")
def test_numeric(self): self.failUnlessEqual(util.tag("~#year"), "Year")
from gi.repository import Gtk from quodlibet import config from quodlibet import qltk from quodlibet import util from quodlibet import _ from quodlibet.browsers._base import FakeDisplayItem, EditDisplayPatternMixin from quodlibet.formats import PEOPLE from quodlibet.qltk import Button, Icons from quodlibet.qltk.ccb import ConfigCheckButton from quodlibet.util import format_rating from quodlibet.util.i18n import numeric_phrase from quodlibet.util.dprint import print_d PEOPLE _SOME_PEOPLE = "\n".join([util.tag("artist"), util.tag("performer"), util.tag("composer"), util.tag("arranger"), ]) _EMPTY = _("Songs not in an album") DEFAULT_PATTERN_TEXT = """[b]<album|<album>|%s>[/b]<date| (<date>)> [small]<~discs|<~discs> - ><~tracks> - <~long-length>[/small] <~people>""" % _EMPTY class Preferences(qltk.UniqueWindow, EditDisplayPatternMixin): _DEFAULT_PATTERN = DEFAULT_PATTERN_TEXT _PREVIEW_ITEM = FakeDisplayItem({ "date": "2010-10-31", "~length": util.format_time_display(6319), "~long-length": util.format_time_long(6319),
def __init__(self, model): songs_text = numeric_phrase("%d duplicate group", "%d duplicate groups", len(model)) super(DuplicateDialog, self).__init__() self.set_destroy_with_parent(True) self.set_title("Quod Libet - %s (%s)" % (Duplicates.PLUGIN_NAME, songs_text)) self.finished = False self.set_default_size(960, 480) self.set_border_width(6) swin = Gtk.ScrolledWindow() swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) swin.set_shadow_type(Gtk.ShadowType.IN) # Set up the browser view view = DuplicateSongsView(model) def cell_text(column, cell, model, iter_, index): text = model[iter_][index] cell.markup = text cell.set_property("markup", text) # Set up the columns for i, (tag, f) in enumerate(DuplicatesTreeModel.TAG_MAP): e = (Pango.EllipsizeMode.START if tag == '~filename' else Pango.EllipsizeMode.END) render = Gtk.CellRendererText() render.set_property("ellipsize", e) col = Gtk.TreeViewColumn(util.tag(tag), render) # Numeric columns are better smaller here. if tag.startswith("~#"): col.set_fixed_width(80) col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) else: col.set_expand(True) col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) col.set_resizable(True) col.set_cell_data_func(render, cell_text, i + 1) view.append_column(col) view.connect('popup-menu', self.__songs_popup_menu) swin.add(view) # A basic information area hbox = Gtk.HBox(spacing=6) def expand_all(*args): model = view.get_model() for row in model: if view.row_expanded(row.path): view.collapse_row(row.path) else: for row in model: view.expand_row(row.path, False) expand = Gtk.Button(_("Collapse / Expand all")) connect_obj(expand, "clicked", expand_all, view) hbox.pack_start(expand, False, True, 0) label = Gtk.Label(label=_("Duplicate key expression is '%s'") % Duplicates.get_key_expression()) hbox.pack_start(label, True, True, 0) close = Button(_("_Close"), Icons.WINDOW_CLOSE) close.connect('clicked', self.__quit) hbox.pack_start(close, False, True, 0) vbox = Gtk.VBox(spacing=6) vbox.pack_start(swin, True, True, 0) vbox.pack_start(hbox, False, True, 0) self.add(vbox) self.show_all()
def test_empty(self): self.failUnlessEqual(util.tag(""), "Invalid tag")
def test_internal(self): self.failUnlessEqual(util.tag("~year"), "Year")
def test_two_nocap(self): self.failUnlessEqual( util.tag("title~version", False), "title / version")
def tag_title(tag: str): if "<" in tag: return util.pattern(tag) return util.tag(tag)
def __init__(self): super(ResultView, self).__init__() self._release_ids = {} render = Gtk.CellRendererPixbuf() column = Gtk.TreeViewColumn(_("Write"), render) def cell_data(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("icon-name", Icons.EDIT) cell.set_sensitive(entry.can_write) column.set_cell_data_func(render, cell_data) column.set_expand(False) column.set_min_width(60) self.append_column(column) self.connect("button-press-event", self.__button_press, column) render = Gtk.CellRendererText() render.set_property("ellipsize", Pango.EllipsizeMode.END) column = Gtk.TreeViewColumn(util.tag("~basename"), render) def cell_data(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.song("~basename")) column.set_cell_data_func(render, cell_data) column.set_expand(True) self.append_column(column) render = Gtk.CellRendererText() render.set_property("ellipsize", Pango.EllipsizeMode.END) column = Gtk.TreeViewColumn(_("Status"), render) def cell_data(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", Status.to_string(entry.status)) column.set_cell_data_func(render, cell_data) column.set_expand(False) column.set_fixed_width(100) self.append_column(column) render = Gtk.CellRendererText() render.set_property("ellipsize", Pango.EllipsizeMode.END) # Translators: album release ID column = Gtk.TreeViewColumn(_("Release"), render) self._release_column = column def cell_data(column, cell, model, iter_, data): entry = model.get_value(iter_) release = entry.release if not release: cell.set_property("text", "-") else: id_ = self.get_release_id(release) cell.set_property("text", str(id_)) column.set_cell_data_func(render, cell_data) column.set_expand(False) self.append_column(column) for tag in ["tracknumber", "artist", "title"]: render = Gtk.CellRendererText() render.set_property("ellipsize", Pango.EllipsizeMode.END) column = Gtk.TreeViewColumn(util.tag(tag), render) def cell_data(column, cell, model, iter_, data, tag=tag): entry = model.get_value(iter_) release = entry.release if not release: cell.set_property("text", "-") else: value = release.tags.get(tag, "-") value = ", ".join(value.split("\n")) cell.set_property("text", value) column.set_cell_data_func(render, cell_data) self.append_column(column) if tag == "tracknumber": self._track_column = column column.set_expand(False) column.set_fixed_width(80) else: column.set_expand(True) for column in self.get_columns(): column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_resizable(True) if column.get_min_width() < 50: column.set_min_width(50) self.set_fixed_height_mode(True)
def test_basic_nocap(self): self.failUnlessEqual(util.tag("title", False), "title")
def test_basic(self): self.failUnlessEqual(util.tag("title"), "Title")
def _format_title(self, tag): """Format the column title based on the tag""" return util.tag(tag)