Exemple #1
0
 def _file(self, songs, box):
     length = 0
     size = 0
     for song in songs:
         length += song.get("~#length", 0)
         try:
             size += filesize(song["~filename"])
         except EnvironmentError:
             pass
     table = Gtk.Table(n_rows=2, n_columns=2)
     table.set_col_spacings(6)
     table.attach(Label(_("Total length:")),
                  0,
                  1,
                  0,
                  1,
                  xoptions=Gtk.AttachOptions.FILL)
     table.attach(Label(util.format_time_long(length)), 1, 2, 0, 1)
     table.attach(Label(_("Total size:")),
                  0,
                  1,
                  1,
                  2,
                  xoptions=Gtk.AttachOptions.FILL)
     table.attach(Label(util.format_size(size)), 1, 2, 1, 2)
     box.pack_start(Frame(_("Files"), table), False, False, 0)
Exemple #2
0
    def _album(self, songs, box):
        text = []

        discs = {}
        for song in songs:
            try:
                discs[song("~#disc")] = int(
                    song["tracknumber"].split("/")[1])
            except (AttributeError, ValueError, IndexError, KeyError):
                discs[song("~#disc")] = max([
                    song("~#track", discs.get(song("~#disc"), 0))])
        tracks = sum(discs.values())
        discs = len(discs)
        length = sum([song.get("~#length", 0) for song in songs])

        if tracks == 0 or tracks < len(songs):
            tracks = len(songs)

        parts = []
        if discs > 1:
            parts.append(
                ngettext("%d disc", "%d discs", discs) % discs)
        parts.append(
                ngettext("%d track", "%d tracks", tracks) % tracks)
        if tracks != len(songs):
            parts.append(ngettext("%d selected", "%d selected",
                len(songs)) % len(songs))

        text.append(", ".join(parts))
        text.append(util.format_time_long(length))

        if "location" in song:
            text.append(util.escape(song["location"]))
        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("")
        w.set_ellipsize(Pango.EllipsizeMode.END)
        w.set_markup("\n".join(text))
        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(hb, False, False, 0)
Exemple #3
0
    def _album(self, songs, box):
        text = []

        discs = {}
        for song in songs:
            try:
                discs[song("~#disc")] = int(
                    song["tracknumber"].split("/")[1])
            except (AttributeError, ValueError, IndexError, KeyError):
                discs[song("~#disc")] = max([
                    song("~#track", discs.get(song("~#disc"), 0))])
        tracks = sum(discs.values())
        discs = len(discs)
        length = sum([song.get("~#length", 0) for song in songs])

        if tracks == 0 or tracks < len(songs):
            tracks = len(songs)

        parts = []
        if discs > 1:
            parts.append(
                ngettext("%d disc", "%d discs", discs) % discs)
        parts.append(
                ngettext("%d track", "%d tracks", tracks) % tracks)
        if tracks != len(songs):
            parts.append(ngettext("%d selected", "%d selected",
                len(songs)) % len(songs))

        text.append(", ".join(parts))
        text.append(util.format_time_long(length))

        if "location" in song:
            text.append(util.escape(song["location"]))
        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("")
        w.set_ellipsize(Pango.EllipsizeMode.END)
        w.set_markup("\n".join(text))
        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(hb, False, False, 0)
Exemple #4
0
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),
        "~tracks": numeric_phrase("%d track", "%d tracks", 5),
        "~discs": numeric_phrase("%d disc", "%d discs", 2),
        "~#rating": 0.75,
        "album": _("An Example Album"),
        "~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(_("Album List Preferences"))
        self.set_default_size(420, 380)
        self.set_transient_for(qltk.get_top_parent(browser))
        # Do this config-driven setup at instance-time
        self._PREVIEW_ITEM["~rating"] = format_rating(0.75)

        box = Gtk.VBox(spacing=6)
        vbox = Gtk.VBox(spacing=6)
        cb = ConfigCheckButton(
            _("Show album _covers"), "browsers", "album_covers")
        cb.set_active(config.getboolean("browsers", "album_covers"))
        cb.connect('toggled', lambda s: browser.toggle_covers())
        vbox.pack_start(cb, False, True, 0)

        cb = ConfigCheckButton(
            _("Inline _search includes people"),
            "browsers", "album_substrings")
        cb.set_active(config.getboolean("browsers", "album_substrings"))
        vbox.pack_start(cb, False, True, 0)
        f = qltk.Frame(_("Options"), child=vbox)
        box.pack_start(f, False, True, 12)

        display_frame = self.edit_display_pane(browser, _("Album Display"))
        box.pack_start(display_frame, True, True, 0)

        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 __set_time(self, info, songs):
     i = len(songs)
     length = sum(song.get("~#length", 0) for song in songs)
     t = self.browser.statusbar(i) % {
         'count': i,
         'time': util.format_time_long(length)
     }
     self.__statusbar.set_text(t)
Exemple #6
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()
 def __set_time(self, *args, **kwargs):
     songs = kwargs.get("songs") or self.songlist.get_selected_songs()
     if "songs" not in kwargs and len(songs) <= 1:
         songs = self.songlist.get_songs()
     i = len(songs)
     length = sum([song("~#length", 0) for song in songs])
     t = self.browser.statusbar(i) % {
         'count': i, 'time': util.format_time_long(length)}
     self.statusbar.set_default_text(t)
Exemple #8
0
    def _album(self, songs, box):
        text = []

        discs = {}
        for song in songs:
            try:
                discs[song("~#disc")] = int(
                    song["tracknumber"].split("/")[1])
            except (AttributeError, ValueError, IndexError, KeyError):
                discs[song("~#disc")] = max([
                    song("~#track", discs.get(song("~#disc"), 0))])
        tracks = sum(discs.values())
        discs = len(discs)
        length = sum([song.get("~#length", 0) for song in songs])

        if tracks == 0 or tracks < len(songs): tracks = len(songs)

        parts = []
        if discs > 1:
            parts.append(
                ngettext("%d disc", "%d discs", discs) % discs)
        parts.append(
                ngettext("%d track", "%d tracks", tracks) % tracks)
        if tracks != len(songs):
            parts.append(ngettext("%d selected", "%d selected",
                len(songs)) % len(songs))

        text.append(", ".join(parts))
        text.append(util.format_time_long(length))

        if "location" in song:
            text.append(util.escape(song["location"]))
        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("")
        w.set_ellipsize(pango.ELLIPSIZE_END)
        w.set_markup("\n".join(text))
        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(hb, expand=False, fill=False)
Exemple #9
0
 def _file(self, songs, box):
     length = 0
     size = 0
     for song in songs:
         length += song.get("~#length", 0)
         try: size += util.size(song["~filename"])
         except EnvironmentError: pass
     table = gtk.Table(2, 2)
     table.set_col_spacings(6)
     table.attach(Label(_("Total length:")), 0, 1, 0, 1,
                  xoptions=gtk.FILL)
     table.attach(
         Label(util.format_time_long(length)), 1, 2, 0, 1)
     table.attach(Label(_("Total size:")), 0, 1, 1, 2,
                  xoptions=gtk.FILL)
     table.attach(Label(util.format_size(size)), 1, 2, 1, 2)
     box.pack_start(Frame(_("Files"), table),
                    expand=False, fill=False)
Exemple #10
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)
Exemple #11
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)
Exemple #12
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)
Exemple #13
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)
Exemple #14
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)
Exemple #15
0
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),
        "~tracks":
        numeric_phrase("%d track", "%d tracks", 5),
        "~discs":
        numeric_phrase("%d disc", "%d discs", 2),
        "~#rating":
        0.75,
        "album":
        _("An Example Album"),
        "~people":
        _SOME_PEOPLE + "..."
    })

    def __init__(self, browser):
        if self.is_not_unique():
            return
        super().__init__()
        self.set_border_width(12)
        self.set_title(_("Cover Grid Preferences"))
        self.set_default_size(420, 380)
        self.set_transient_for(qltk.get_top_parent(browser))
        # Do this config-driven setup at instance-time
        self._PREVIEW_ITEM["~rating"] = format_rating(0.75)
        self.mag_lock = False

        box = Gtk.VBox(spacing=6)
        vbox = Gtk.VBox(spacing=6)
        cb = ConfigCheckButton(_("Show album _text"), "browsers", "album_text")
        cb.set_active(config.getboolean("browsers", "album_text"))
        cb.connect('toggled', lambda s: browser.toggle_text())
        vbox.pack_start(cb, False, True, 0)

        cb2 = ConfigCheckButton(_("Show \"All Albums\" Item"), "browsers",
                                "covergrid_all")
        cb2.set_active(config.getboolean("browsers", "covergrid_all", True))

        def refilter(s):
            mod = browser.view.get_model()
            if mod:
                mod.refilter()

        cb2.connect('toggled', refilter)
        vbox.pack_start(cb2, False, True, 0)

        cb3 = ConfigCheckButton(_("Wide Mode"), "browsers", "covergrid_wide")
        cb3.set_active(config.getboolean("browsers", "covergrid_wide", False))
        cb3.connect('toggled', lambda s: browser.toggle_wide())
        vbox.pack_start(cb3, False, True, 0)

        # Redraws the covers only when the user releases the slider
        def mag_button_press(*_):
            self.mag_lock = True

        def mag_button_release(mag, _):
            self.mag_lock = False
            mag_changed(mag)

        def mag_changed(mag):
            if self.mag_lock:
                return
            newmag = mag.get_value()
            oldmag = config.getfloat("browsers", "covergrid_magnification", 3.)
            if newmag == oldmag:
                print_d("Covergrid magnification haven't changed: {0}".format(
                    newmag))
                return
            print_d('Covergrid magnification update from {0} to {1}'.format(
                oldmag, newmag))
            config.set("browsers", "covergrid_magnification", mag.get_value())
            browser.update_mag()

        mag_scale = Gtk.HScale(adjustment=Gtk.Adjustment.new(
            config.getfloat("browsers", "covergrid_magnification", 3), 0., 10.,
            .5, .5, 0))
        mag_scale.set_tooltip_text(_("Cover Magnification"))
        l = Gtk.Label(label=_("Cover Magnification"))
        mag_scale.set_value_pos(Gtk.PositionType.RIGHT)
        mag_scale.connect('button-press-event', mag_button_press)
        mag_scale.connect('button-release-event', mag_button_release)
        mag_scale.connect('value-changed', mag_changed)

        vbox.pack_start(l, False, True, 0)
        vbox.pack_start(mag_scale, False, True, 0)

        f = qltk.Frame(_("Options"), child=vbox)
        box.pack_start(f, False, True, 12)

        display_frame = self.edit_display_pane(browser, _("Album Display"))
        box.pack_start(display_frame, True, True, 0)

        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()
Exemple #16
0
 def __set_time(self, info, songs):
     i = len(songs)
     length = sum(song.get("~#length", 0) for song in songs)
     t = self.browser.status_text(count=i,
                                  time=util.format_time_long(length))
     self.__statusbar.set_text(t)
    def __get_value(self, key):
        """This is similar to __call__ in the AudioFile class.
        All internal tags are changed to represent a collection of songs.
        """

        # Using key:<func> runs the resulting list of values
        # through the function before returning it.
        # Numeric keys without a func will default to a reasonable function
        if key.startswith("~#"):
            key = key[2:]

            if key[-4:-3] == ":":
                func = key[-3:]
                key = key[:-4]
            elif key == "tracks":
                return len(self.songs)
            elif key == "discs":
                return len(set([song("~#disc", 1) for song in self.songs]))
            elif key == "bitrate":
                length = self.__get_value("~#length")
                if not length:
                    return 0
                w = lambda s: s("~#bitrate", 0) * s("~#length", 0)
                return sum(w(song) for song in self.songs) / length
            else:
                # Standard or unknown numeric key.
                # AudioFile will try to cast the values to int,
                # default to avg
                func = NUM_DEFAULT_FUNCS.get(key, "avg")

            key = "~#" + key
            func = NUM_FUNCS.get(func)
            if func:
                # If none of the songs can return a numeric key,
                # the album returns default
                values = (song(key) for song in self.songs)
                values = [v for v in values if v != ""]
                return func(values) if values else None
            elif key in INTERN_NUM_DEFAULT:
                return 0
            return None
        elif key[:1] == "~":
            key = key[1:]
            keys = {"people": {}, "peoplesort": {}}
            if key in keys:
                people = keys["people"]
                peoplesort = keys["peoplesort"]
                for song in self.songs:
                    # Rank people by "relevance" -- artists before composers
                    # before performers, then by number of appearances.
                    for w, k in enumerate(ELPOEP):
                        persons = song.list(k)
                        for person in persons:
                            people[person] = (people.get(person, 0) -
                                              PEOPLE_SCORE[w])
                        if k in TAG_TO_SORT:
                            persons = song.list(TAG_TO_SORT[k]) or persons
                        for person in persons:
                            peoplesort[person] = (peoplesort.get(person, 0) -
                                                  PEOPLE_SCORE[w])
                # It's cheaper to get people and peoplesort in one go
                keys["people"] = sorted(people.keys(),
                                        key=people.__getitem__)[:100]
                keys["peoplesort"] = sorted(peoplesort.keys(),
                                            key=peoplesort.__getitem__)[:100]

                ret = keys.pop(key)
                ret = (ret and "\n".join(ret)) or None

                other, values = keys.popitem()
                other = "~" + other
                if not values:
                    self.__default.add(other)
                else:
                    if other in self.__used:
                        self.__used.remove(other)
                    self.__used.append(other)
                    self.__cache[other] = "\n".join(values)
                return ret
            elif key == "length":
                length = self.__get_value("~#length")
                return None if length is None else util.format_time(length)
            elif key == "long-length":
                length = self.__get_value("~#length")
                return (None
                        if length is None else util.format_time_long(length))
            elif key == "tracks":
                tracks = self.__get_value("~#tracks")
                return (None if tracks is None else
                        ngettext("%d track", "%d tracks", tracks) % tracks)
            elif key == "discs":
                discs = self.__get_value("~#discs")
                if discs > 1:
                    return ngettext("%d disc", "%d discs", discs) % discs
                else:
                    # TODO: check this is correct for discs == 1
                    return None
            elif key == "rating":
                rating = self.__get_value("~#rating")
                if rating is None:
                    return None
                return util.format_rating(rating)
            elif key == "cover":
                return ((self.cover != type(self).cover) and "y") or None
            elif key == "filesize":
                size = self.__get_value("~#filesize")
                return None if size is None else util.format_size(size)
            key = "~" + key

        # Nothing special was found, so just take all values of the songs
        # and sort them by their number of appearance
        result = {}
        for song in self.songs:
            for value in song.list(key):
                result[value] = result.get(value, 0) - 1

        values = map(lambda x: x[0], sorted(result.items(),
                                            key=lambda x: x[1]))
        return "\n".join(values) if values else None
 def __set_time(self, info, songs):
     i = len(songs)
     length = sum(song.get("~#length", 0) for song in songs)
     t = self.browser.statusbar(i) % {
         'count': i, 'time': util.format_time_long(length)}
     self.statusbar.set_default_text(t)
Exemple #19
0
class Preferences(qltk.UniqueWindow):

    _EXAMPLE_ALBUM = FakeAlbum({
        "date":
        "2010-10-31",
        "~length":
        util.format_time_display(6319),
        "~long-length":
        util.format_time_long(6319),
        "~tracks":
        ngettext("%d track", "%d tracks", 5) % 5,
        "~discs":
        ngettext("%d disc", "%d discs", 2) % 2,
        "~#rating":
        0.75,
        "album":
        _("An Example Album"),
        "~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(_("Album List Preferences") + " - Quod Libet")
        self.set_default_size(420, 380)
        self.set_transient_for(qltk.get_top_parent(browser))
        # Do this config-driven setup at instance-time
        self._EXAMPLE_ALBUM["~rating"] = format_rating(0.75)

        box = Gtk.VBox(spacing=6)
        vbox = Gtk.VBox(spacing=6)
        cb = ConfigCheckButton(_("Show album _covers"), "browsers",
                               "album_covers")
        cb.set_active(config.getboolean("browsers", "album_covers"))
        cb.connect('toggled', lambda s: browser.toggle_covers())
        vbox.pack_start(cb, False, True, 0)

        cb = ConfigCheckButton(_("Inline _search includes people"), "browsers",
                               "album_substrings")
        cb.set_active(config.getboolean("browsers", "album_substrings"))
        vbox.pack_start(cb, False, True, 0)
        f = qltk.Frame(_("Options"), child=vbox)
        box.pack_start(f, False, True, 12)

        vbox = Gtk.VBox(spacing=6)
        label = Gtk.Label()
        label.set_alignment(0.0, 0.5)
        label.set_padding(6, 6)
        eb = Gtk.EventBox()
        eb.get_style_context().add_class("entry")
        eb.add(label)

        edit = PatternEditBox(PATTERN)
        edit.text = browser._pattern_text
        edit.apply.connect('clicked', self.__set_pattern, edit, browser)
        connect_obj(edit.buffer, 'changed', self.__preview_pattern, edit,
                    label)

        vbox.pack_start(eb, False, True, 3)
        vbox.pack_start(edit, True, True, 0)
        self.__preview_pattern(edit, label)
        f = qltk.Frame(_("Album Display"), child=vbox)
        box.pack_start(f, True, True, 0)

        main_box = Gtk.VBox(spacing=12)
        close = Gtk.Button(stock=Gtk.STOCK_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 __set_pattern(self, apply, edit, browser):
        browser.refresh_pattern(edit.text)

    def __preview_pattern(self, edit, label):
        try:
            text = XMLFromMarkupPattern(edit.text) % self._EXAMPLE_ALBUM
        except:
            text = _("Invalid pattern")
            edit.apply.set_sensitive(False)
        try:
            Pango.parse_markup(text, -1, u"\u0000")
        except GLib.GError:
            text = _("Invalid pattern")
            edit.apply.set_sensitive(False)
        else:
            edit.apply.set_sensitive(True)
        label.set_markup(text)
Exemple #20
0
    def __get_value(self, key):
        """This is similar to __call__ in the AudioFile class.
        All internal tags are changed to represent a collection of songs.
        """

        # Using key:<func> runs the resulting list of values
        # through the function before returning it.
        # Numeric keys without a func will default to a reasonable function
        if key.startswith("~#"):
            key = key[2:]

            if key[-4:-3] == ":":
                func = key[-3:]
                key = key[:-4]
            elif key == "tracks":
                return len(self.songs)
            elif key == "discs":
                return len(set([song("~#disc", 1) for song in self.songs]))
            elif key == "bitrate":
                length = self.__get_value("~#length")
                if not length: return 0
                w = lambda s: s("~#bitrate", 0) * s("~#length", 0)
                return sum(w(song) for song in self.songs) / length
            elif key in NUM_DEFAULT_FUNCS:
                func = NUM_DEFAULT_FUNCS[key]
            else:
                #Unknown key. AudioFile will try to cast the values to int,
                #default to avg
                func = "avg"

            key = "~#" + key

            func = NUM_FUNCS.get(func)
            if func:
                #if none of the songs can return a numeric key
                #the album returns default
                values = (song(key) for song in self.songs)
                values = [v for v in values if v != ""]
                if values: return func(values)
                else: return None
            elif key in INTERN_NUM_DEFAULT:
                return 0
            return None
        elif key[:1] == "~":
            key = key[1:]
            keys = {"people": {}, "peoplesort": {}}
            if key in keys:
                people = keys["people"]
                peoplesort = keys["peoplesort"]
                for song in self.songs:
                    # Rank people by "relevance" -- artists before composers
                    # before performers, then by number of appearances.
                    for w, k in enumerate(ELPOEP):
                        persons = song.list(k)
                        for person in persons:
                            people[person] = (people.get(person, 0) -
                                              PEOPLE_SCORE[w])
                        if k in TAG_TO_SORT:
                            persons = song.list(TAG_TO_SORT[k]) or persons
                        for person in persons:
                            peoplesort[person] = (peoplesort.get(person, 0) -
                                                  PEOPLE_SCORE[w])
                #It's cheaper to get people and peoplesort in one go
                keys["people"] = sorted(people.keys(),
                    key=people.__getitem__)[:100]
                keys["peoplesort"] = sorted(peoplesort.keys(),
                    key=peoplesort.__getitem__)[:100]

                ret = keys.pop(key)
                ret = (ret and "\n".join(ret)) or None

                other, values = keys.popitem()
                other = "~" + other
                if not values:
                    self.__default.add(other)
                else:
                    if other in self.__used:
                        self.__used.remove(other)
                    self.__used.append(other)
                    self.__cache[other] = "\n".join(values)

                return ret
            elif key == "length":
                length = self.__get_value("~#length")
                if length is None: return None
                return util.format_time(length)
            elif key == "long-length":
                length = self.__get_value("~#length")
                if length is None: return None
                return util.format_time_long(length)
            elif key == "tracks":
                tracks = self.__get_value("~#tracks")
                if tracks is None: return None
                return ngettext("%d track", "%d tracks", tracks) % tracks
            elif key == "discs":
                discs = self.__get_value("~#discs")
                if discs > 1:
                    return ngettext("%d disc", "%d discs", discs) % discs
                else: return None
            elif key == "rating":
                rating = self.__get_value("~#rating")
                if rating is None: return None
                return util.format_rating(rating)
            elif key == "cover":
                return ((self.cover != type(self).cover) and "y") or None
            elif key == "filesize":
                size = self.__get_value("~#filesize")
                if size is None: return None
                return util.format_size(size)
            key = "~" + key

        #Nothing special was found, so just take all values of the songs
        #and sort them by their number of appearance
        result = {}
        for song in self.songs:
            for value in song.list(key):
                result[value] = result.get(value, 0) - 1

        values = map(lambda x: x[0],
            sorted(result.items(), key=lambda x: x[1]))
        if not values: return None
        return "\n".join(values)
Exemple #21
0
 def __set_time(self, info, songs):
     i = len(songs)
     length = sum(song.get("~#length", 0) for song in songs)
     t = self.browser.status_text(count=i,
                                  time=util.format_time_long(length))
     self.__statusbar.set_text(t)