Ejemplo n.º 1
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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
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)
Ejemplo n.º 4
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)
Ejemplo n.º 5
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)
Ejemplo n.º 6
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)
Ejemplo n.º 7
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
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
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.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)
Ejemplo n.º 10
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), Icons.EDIT_FIND)
     b.connect('activate', self.__filter_on, t, songs, browser)
     return b
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
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)
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
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)
Ejemplo n.º 16
0
    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()
Ejemplo n.º 17
0
    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
Ejemplo n.º 18
0
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()
Ejemplo n.º 19
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)
Ejemplo n.º 20
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)
Ejemplo n.º 21
0
 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)
Ejemplo n.º 22
0
    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)
Ejemplo n.º 23
0
    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)
Ejemplo n.º 24
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)
Ejemplo n.º 25
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
Ejemplo n.º 26
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
Ejemplo n.º 27
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)
Ejemplo n.º 28
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
Ejemplo n.º 29
0
    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
Ejemplo n.º 30
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(str(song.comma(col))) or '&nbsp;')
        s += '</tr>'
        songs_s += s

    return HTML % {'headers': cols_s, 'songs': songs_s}
Ejemplo n.º 31
0
    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")
Ejemplo n.º 32
0
    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")
Ejemplo n.º 33
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)
Ejemplo n.º 34
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)
Ejemplo n.º 35
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 '&nbsp;')
        s += '</tr>'
        songs_s += s

    return HTML % {'headers': cols_s, 'songs': songs_s}
Ejemplo n.º 36
0
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
Ejemplo n.º 37
0
    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)
Ejemplo n.º 38
0
    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)
Ejemplo n.º 39
0
 def test_precap_handling(self):
     self.failUnlessEqual(util.tag("labelid"), "Label ID")
     self.failUnlessEqual(util.tag("labelid", False), "label ID")
Ejemplo n.º 40
0
 def test_two_nocap(self):
     self.failUnlessEqual(util.tag("title~version", False),
                          "title / version")
Ejemplo n.º 41
0
 def test_two(self):
     self.failUnlessEqual(util.tag("title~version"), "Title / Version")
Ejemplo n.º 42
0
 def test_numeric(self):
     self.failUnlessEqual(util.tag("~#year"), "Year")
Ejemplo n.º 43
0
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),
Ejemplo n.º 44
0
    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()
Ejemplo n.º 45
0
 def test_empty(self):
     self.failUnlessEqual(util.tag(""), "Invalid tag")
Ejemplo n.º 46
0
 def test_two(self):
     self.failUnlessEqual(util.tag("title~version"), "Title / Version")
Ejemplo n.º 47
0
 def test_internal(self):
     self.failUnlessEqual(util.tag("~year"), "Year")
Ejemplo n.º 48
0
 def test_two_nocap(self):
     self.failUnlessEqual(
         util.tag("title~version", False), "title / version")
Ejemplo n.º 49
0
 def test_precap_handling(self):
     self.failUnlessEqual(util.tag("labelid"), "Label ID")
     self.failUnlessEqual(util.tag("labelid", False), "label ID")
Ejemplo n.º 50
0
 def tag_title(tag: str):
     if "<" in tag:
         return util.pattern(tag)
     return util.tag(tag)
Ejemplo n.º 51
0
    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)
Ejemplo n.º 52
0
 def test_basic_nocap(self):
     self.failUnlessEqual(util.tag("title", False), "title")
Ejemplo n.º 53
0
 def test_numeric(self):
     self.failUnlessEqual(util.tag("~#year"), "Year")
Ejemplo n.º 54
0
 def test_internal(self):
     self.failUnlessEqual(util.tag("~year"), "Year")
Ejemplo n.º 55
0
 def test_basic(self):
     self.failUnlessEqual(util.tag("title"), "Title")
Ejemplo n.º 56
0
    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()
Ejemplo n.º 57
0
    def _format_title(self, tag):
        """Format the column title based on the tag"""

        return util.tag(tag)
Ejemplo n.º 58
0
 def test_basic_nocap(self):
     self.failUnlessEqual(util.tag("title", False), "title")