コード例 #1
0
ファイル: information.py プロジェクト: urielz/quodlibet
    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_preferred(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)
コード例 #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_preferred(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)
コード例 #3
0
 def plugin_songs(self, songs):
     desc = ngettext("%d song", "%d songs", len(songs)) % len(songs)
     win = ConsoleWindow(create_console(songs), title=desc)
     win.set_icon_name(self.PLUGIN_ICON)
     win.set_title(_("{plugin_name} for {songs} ({app})").format(
         plugin_name=self.PLUGIN_NAME, songs=desc, app=app.name))
     win.show_all()
コード例 #4
0
def do_import(parent, library):
    db_path = expanduser(BansheeImport.USR_PATH)

    importer = BansheeDBImporter(library)
    try:
        db = sqlite3.connect(db_path)
        importer.read(db)
        db.close()
    except sqlite3.OperationalError:
        msg = _("Specified Banshee database is malformed or missing")
        WarningMessage(parent, BansheeImport.PLUGIN_NAME, msg).run()
    except Exception:
        util.print_exc()
        importer.finish()
        msg = _("Import Failed")
        # FIXME: don't depend on the plugin class here
        ErrorMessage(parent, BansheeImport.PLUGIN_NAME, msg).run()
    else:
        count = importer.finish()
        msg = ngettext(
            "Successfully imported ratings and statistics for %d song",
            "Successfully imported ratings and statistics for %d songs",
            count) % count
        Message(Gtk.MessageType.INFO, parent, BansheeImport.PLUGIN_NAME,
                msg).run()
コード例 #5
0
ファイル: console.py プロジェクト: zsau/quodlibet
 def plugin_songs(self, songs):
     desc = ngettext("%d song", "%d songs", len(songs)) % len(songs)
     win = ConsoleWindow(create_console(songs), title=desc)
     win.set_icon_name(self.PLUGIN_ICON)
     win.set_title(_("{plugin_name} for {songs} ({app})").format(
         plugin_name=self.PLUGIN_NAME, songs=desc, app=app.name))
     win.show_all()
コード例 #6
0
    def _album(self, songs, box):
        albums, noalbum = _sort_albums(songs)

        def format(args):
            date, song, album = args
            markup = "<big><i>%s</i></big>" % util.escape(album)
            return "%s (%s)" % (markup, date[:4]) if date else markup

        get_cover = app.cover_manager.get_cover
        covers = [(a, get_cover(s), s) for d, s, a in albums]
        albums = [format(a) for a in albums]
        if noalbum:
            albums.append(ngettext("%d song with no album",
                "%d songs with no album", noalbum) % noalbum)
        l = Label(markup="\n".join(albums), ellipsize=True)
        box.pack_start(Frame(_("Selected Discography"), l), False, False, 0)

        covers = [ac for ac in covers if bool(ac[1])]
        t = Gtk.Table(n_rows=4, n_columns=(len(covers) // 4) + 1)
        t.set_col_spacings(12)
        t.set_row_spacings(12)
        added = set()
        for i, (album, cover, song) in enumerate(covers):
            if cover.name in added:
                continue
            cov = ReactiveCoverImage(song=song, tooltip=album)
            c = i % 4
            r = i // 4
            t.attach(cov, c, c + 1, r, r + 1,
                     xoptions=Gtk.AttachOptions.EXPAND, yoptions=0)
            added.add(cover.name)
        box.pack_start(t, True, True, 0)
コード例 #7
0
ファイル: information.py プロジェクト: LudoBike/quodlibet
    def _album(self, songs, box):
        albums, noalbum = _sort_albums(songs)

        def format(args):
            date, song, album = args
            markup = "<big><i>%s</i></big>" % util.escape(album)
            return "%s (%s)" % (markup, date[:4]) if date else markup

        get_cover = app.cover_manager.get_cover
        covers = [(a, get_cover(s), s) for d, s, a in albums]
        albums = [format(a) for a in albums]
        if noalbum:
            albums.append(ngettext("%d song with no album",
                "%d songs with no album", noalbum) % noalbum)
        l = Label(markup="\n".join(albums), ellipsize=True)
        box.pack_start(Frame(_("Selected Discography"), l), False, False, 0)

        covers = [ac for ac in covers if bool(ac[1])]
        t = Gtk.Table(n_rows=4, n_columns=(len(covers) // 4) + 1)
        t.set_col_spacings(12)
        t.set_row_spacings(12)
        added = set()
        for i, (album, cover, song) in enumerate(covers):
            if cover.name in added:
                continue
            cov = ReactiveCoverImage(song=song, tooltip=album)
            c = i % 4
            r = i // 4
            t.attach(cov, c, c + 1, r, r + 1,
                     xoptions=Gtk.AttachOptions.EXPAND, yoptions=0)
            added.add(cover.name)
        box.pack_start(t, True, True, 0)
コード例 #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("(%s)" % util.format_time_preferred(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(markup="\n".join(text), ellipsize=True)
        hb = Gtk.HBox(spacing=12)
        hb.pack_start(w, True, True, 0)
        hb.pack_start(ReactiveCoverImage(song=song), False, True, 0)

        box.pack_start(hb, False, False, 0)
コード例 #9
0
ファイル: information.py プロジェクト: elfalem/quodlibet
    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("(%s)" % util.format_time_preferred(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(markup="\n".join(text), ellipsize=True)
        hb = Gtk.HBox(spacing=12)
        hb.pack_start(w, True, True, 0)
        hb.pack_start(ReactiveCoverImage(song=song), False, True, 0)

        box.pack_start(hb, False, False, 0)
コード例 #10
0
def confirm_multi_album_invoke(parent, plugin_name, count):
    """Dialog to confirm invoking a plugin with X albums in case X is high"""
    title = ngettext("Run the plugin \"%(name)s\" on %(count)d album?",
                     "Run the plugin \"%(name)s\" on %(count)d albums?",
                     count) % {"name": plugin_name, "count": count}
    description = ""
    ok_text = _("_Run Plugin")
    prompt = ConfirmationPrompt(parent, title, description, ok_text).run()
    return prompt == ConfirmationPrompt.RESPONSE_INVOKE
コード例 #11
0
ファイル: songsmenu.py プロジェクト: zsau/quodlibet
def confirm_multi_album_invoke(parent, plugin_name, count):
    """Dialog to confirm invoking a plugin with X albums in case X is high"""
    title = ngettext("Run the plugin \"%(name)s\" on %(count)d album?",
                     "Run the plugin \"%(name)s\" on %(count)d albums?",
                     count) % {"name": plugin_name, "count": count}
    description = ""
    ok_text = _("_Run Plugin")
    prompt = ConfirmationPrompt(parent, title, description, ok_text).run()
    return prompt == ConfirmationPrompt.RESPONSE_INVOKE
コード例 #12
0
ファイル: queue.py プロジェクト: elfalem/quodlibet
 def __update_count(self, model, path, lab):
     if len(model) == 0:
         text = ""
     else:
         time = sum([row[0].get("~#length", 0) for row in model])
         text = ngettext("%(count)d song (%(time)s)",
                         "%(count)d songs (%(time)s)",
                         len(model)) % {
             "count": len(model), "time": format_time_preferred(time)}
     lab.set_text(text)
コード例 #13
0
 def __update_count(self, model, path, lab):
     if len(model) == 0:
         text = ""
     else:
         time = sum([row[0].get("~#length", 0) for row in model])
         text = ngettext("%(count)d song (%(time)s)",
                         "%(count)d songs (%(time)s)",
                         len(model)) % {
             "count": len(model), "time": format_time_preferred(time)}
     lab.set_text(text)
コード例 #14
0
 def suggested_name_for(cls, songs):
     if len(songs) == 1:
         title = songs[0].comma("title")
     else:
         title = ngettext(
                 "%(title)s and %(count)d more",
                 "%(title)s and %(count)d more",
                 len(songs) - 1) % (
                     {'title': songs[0].comma("title"),
                      'count': len(songs) - 1})
     return title
コード例 #15
0
ファイル: collection.py プロジェクト: ZDBioHazard/quodlibet
 def suggested_name_for(cls, songs):
     if len(songs) == 1:
         title = songs[0].comma("title")
     else:
         title = ngettext(
                 "%(title)s and %(count)d more",
                 "%(title)s and %(count)d more",
                 len(songs) - 1) % (
                     {'title': songs[0].comma("title"),
                      'count': len(songs) - 1})
     return title
コード例 #16
0
 def suggested_name_for(songs):
     if len(songs) == 0:
         return _("Empty Playlist")
     elif len(songs) == 1:
         return songs[0].comma("title")
     else:
         return ngettext("%(title)s and %(count)d more",
                         "%(title)s and %(count)d more",
                         len(songs) - 1) % ({
                             "title": songs[0].comma("title"),
                             "count": len(songs) - 1
                         })
コード例 #17
0
ファイル: playlist.py プロジェクト: azarmadr/quodlibet
def confirm_multi_playlist_invoke(parent, plugin_name, count):
    """Dialog to confirm invoking a plugin with X playlists
    in case X is high
    """
    params = {"name": plugin_name, "count": format_int_locale(count)}
    title = ngettext("Run the plugin \"%(name)s\" on %(count)s playlist?",
                     "Run the plugin \"%(name)s\" on %(count)s playlists?",
                     count) % params
    description = ""
    ok_text = _("_Run Plugin")
    prompt = ConfirmationPrompt(parent, title, description, ok_text).run()
    return prompt == ConfirmationPrompt.RESPONSE_INVOKE
コード例 #18
0
ファイル: playlist.py プロジェクト: LudoBike/quodlibet
def confirm_multi_playlist_invoke(parent, plugin_name, count):
    """Dialog to confirm invoking a plugin with X playlists
    in case X is high
    """
    params = {"name": plugin_name, "count": format_int_locale(count)}
    title = ngettext("Run the plugin \"%(name)s\" on %(count)s playlist?",
                     "Run the plugin \"%(name)s\" on %(count)s playlists?",
                     count) % params
    description = ""
    ok_text = _("_Run Plugin")
    prompt = ConfirmationPrompt(parent, title, description, ok_text).run()
    return prompt == ConfirmationPrompt.RESPONSE_INVOKE
コード例 #19
0
    def _update_sync_summary(self):
        """
        Update the synchronization summary text field.
        """
        sync_summary_prefix = _('Synchronization has:') + self.summary_sep
        sync_summary = []

        if self.c_files_copy > 0 or self.c_files_skip > 0:
            text = []

            counter = self.c_files_copy
            text.append(
                ngettext('written {count}/{total} file',
                         'written {count}/{total} files',
                         counter).format(count=counter,
                                         total=self.c_songs_copy))

            if self.c_files_skip > 0:
                counter = self.c_files_skip
                text.append(
                    ngettext('(skipped {count} existing file)',
                             '(skipped {count} existing files)',
                             counter).format(count=counter))

            sync_summary.append(self.summary_sep.join(text))

        if self.c_files_dupes > 0:
            counter = self.c_files_dupes
            sync_summary.append(
                ngettext('skipped {count}/{total} duplicate file',
                         'skipped {count}/{total} duplicate files',
                         counter).format(count=counter,
                                         total=self.c_song_dupes))

        if self.c_files_delete > 0:
            counter = self.c_files_delete
            sync_summary.append(
                ngettext('deleted {count}/{total} file',
                         'deleted {count}/{total} files',
                         counter).format(count=counter,
                                         total=self.c_songs_delete))

        if self.c_files_failed > 0:
            counter = self.c_files_failed
            sync_summary.append(
                ngettext('failed to sync {count} file',
                         'failed to sync {count} files',
                         counter).format(count=counter))

        if self.c_files_skip_previous > 0:
            counter = self.c_files_skip_previous
            sync_summary.append(
                ngettext('skipped {count} file synchronized previously',
                         'skipped {count} files synchronized previously',
                         counter).format(count=counter))

        sync_summary_text = self.summary_sep_list.join(sync_summary)
        sync_summary_text = sync_summary_prefix + sync_summary_text
        self.status_progress.set_label(sync_summary_text)
        print_d(sync_summary_text)
コード例 #20
0
    def __init__(self, parent, playlist, songs):

        desc = ngettext("What do you want to do with that %d song?",
                        "What do you want to do with those %d songs?",
                        len(songs)) % len(songs)

        title = _("Confirm action for playlist \"%s\"") % playlist.name
        super().__init__(Gtk.MessageType.QUESTION, parent, title, desc,
                         Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Add"), Icons.LIST_ADD, self.ADD)
        self.add_icon_button(_("_Remove"), Icons.LIST_REMOVE, self.REMOVE)
コード例 #21
0
    def _update_preview_summary(self):
        """
        Update the preview summary text field.
        """
        prefix = _('Synchronization will:') + self.summary_sep
        preview_progress = []

        if self.c_songs_copy > 0:
            counter = self.c_songs_copy
            preview_progress.append(
                ngettext('attempt to write {count} file',
                         'attempt to write {count} files',
                         counter).format(count=counter))

        if self.c_song_dupes > 0:
            counter = self.c_song_dupes
            preview_progress.append(
                ngettext('skip {count} duplicate file',
                         'skip {count} duplicate files',
                         counter).format(count=counter))
            for child in self.status_duplicates.get_children():
                child.set_visible(True)
            self.status_duplicates.set_visible(True)

        if self.c_songs_delete > 0:
            counter = self.c_songs_delete
            preview_progress.append(
                ngettext('delete {count} file', 'delete {count} files',
                         counter).format(count=counter))
            for child in self.status_deletions.get_children():
                child.set_visible(True)
            self.status_deletions.set_visible(True)

        preview_progress_text = self.summary_sep_list.join(preview_progress)
        if preview_progress_text:
            preview_progress_text = prefix + preview_progress_text
            self.status_progress.set_label(preview_progress_text)
            self.status_progress.set_visible(True)
            print_d(preview_progress_text)
コード例 #22
0
    def _album(self, songs, box):
        noalbum = 0
        albums = {}
        for song in songs:
            if "album" in song:
                albums[song.list("album")[0]] = song
            else:
                noalbum += 1
        albums = [(song.get("date"), song, album)
                  for album, song in albums.items()]
        albums.sort()

        def format(args):
            date, song, album = args
            if date:
                return "%s (%s)" % (album, date[:4])
            else:
                return album

        get_cover = app.cover_manager.get_cover
        covers = [(a, get_cover(s), s) for d, s, a in albums]
        albums = map(format, albums)
        if noalbum:
            albums.append(
                ngettext("%d song with no album", "%d songs with no album",
                         noalbum) % noalbum)
        l = Label("\n".join(albums))
        l.set_ellipsize(Pango.EllipsizeMode.END)
        box.pack_start(Frame(_("Selected Discography"), l), False, False, 0)

        covers = [ac for ac in covers if bool(ac[1])]
        t = Gtk.Table(n_rows=4, n_columns=(len(covers) // 4) + 1)
        t.set_col_spacings(12)
        t.set_row_spacings(12)
        added = set()
        for i, (album, cover, song) in enumerate(covers):
            if cover.name in added:
                continue
            cov = CoverImage(song=song)
            cov.get_child().set_tooltip_text(album)
            c = i % 4
            r = i // 4
            t.attach(cov,
                     c,
                     c + 1,
                     r,
                     r + 1,
                     xoptions=Gtk.AttachOptions.EXPAND,
                     yoptions=0)
            added.add(cover.name)
        box.pack_start(t, True, True, 0)
コード例 #23
0
    def __init__(self, parent, playlist, count):
        title = ngettext("Are you sure you want to remove %d duplicate song?",
                         "Are you sure you want to remove %d duplicate songs?",
                         count) % count
        description = (_("The duplicate songs will be removed "
                         "from the playlist '%s'.") % playlist.name)

        super(ConfirmRemoveDuplicatesDialog, self).__init__(
            Gtk.MessageType.WARNING, parent, title, description,
            Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Remove"), Icons.LIST_REMOVE,
                             Gtk.ResponseType.YES)
コード例 #24
0
    def __init__(self, parent, playlist, count):
        title = ngettext(
            "Are you sure you want to remove %d duplicate song?",
            "Are you sure you want to remove %d duplicate songs?",
            count) % count
        description = (_("The duplicate songs will be removed "
                         "from the playlist '%s'.") % playlist.name)

        super().__init__(Gtk.MessageType.WARNING, parent, title, description,
                         Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Remove"), Icons.LIST_REMOVE,
                             Gtk.ResponseType.YES)
コード例 #25
0
ファイル: songsmenu.py プロジェクト: zsau/quodlibet
def confirm_song_removal_invoke(parent, songs):
    songs = set(songs)
    if not songs:
        return True

    count = len(songs)
    song = next(iter(songs))
    title = (ngettext("Remove track: \"%%(title)s\" from library?",
                     "Remove %(count)d tracks from library?",
                     count) % {'count': count}) % {
                        'title': song('title') or song('~basename')}

    return ConfirmationPrompt.RESPONSE_INVOKE == ConfirmationPrompt(
               parent, title, "", _("Remove from Library")).run()
コード例 #26
0
ファイル: songsmenu.py プロジェクト: slackmage/quodlibet
def confirm_song_removal_invoke(parent, songs):
    songs = set(songs)
    if not songs:
        return True

    count = len(songs)
    song = next(iter(songs))
    title = (ngettext("Remove track: \"%%(title)s\" from library?",
                     "Remove %(count)d tracks from library?",
                     count) % {'count': count}) % {
                        'title': song('title') or song('~basename')}

    return ConfirmationPrompt.RESPONSE_INVOKE == ConfirmationPrompt(
               parent, title, "", _("Remove from Library")).run()
コード例 #27
0
ファイル: songsmenu.py プロジェクト: elfalem/quodlibet
    def __init__(self, parent, plugin_name, count):
        title = ngettext("Run the plugin \"%(name)s\" on %(count)d album?",
                         "Run the plugin \"%(name)s\" on %(count)d albums?",
                         count) % {'name': plugin_name, 'count': count}

        super(ConfirmMultiAlbumInvoke, self).__init__(
            get_top_parent(parent),
            title, "",
            buttons=Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Run Plugin"), Icons.SYSTEM_RUN,
                             self.RESPONSE_INVOKE)
        self.set_default_response(Gtk.ResponseType.CANCEL)
コード例 #28
0
ファイル: menu.py プロジェクト: ZDBioHazard/quodlibet
    def __init__(self, parent, playlist, songs):

        desc = ngettext("What do you want to do with that %d song?",
                        "What do you want to do with those %d songs?",
                        len(songs)) % len(songs)

        title = _("Confirm action for playlist \"%s\"") % playlist.name
        super(ConfirmMultipleSongsAction, self).__init__(
            Gtk.MessageType.QUESTION, parent, title, desc,
            Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Add"), Icons.LIST_ADD, self.ADD)
        self.add_icon_button(_("_Remove"), Icons.LIST_REMOVE, self.REMOVE)
コード例 #29
0
ファイル: songsmenu.py プロジェクト: tonydolan/quodlibet
    def __init__(self, parent, plugin_name, count):
        title = ngettext("Run the plugin \"%(name)s\" on %(count)d album?",
                         "Run the plugin \"%(name)s\" on %(count)d albums?",
                         count) % {'name': plugin_name, 'count': count}

        super(ConfirmMultiAlbumInvoke, self).__init__(
            get_top_parent(parent),
            title, "",
            buttons=Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Run Plugin"), Icons.SYSTEM_RUN,
                             self.RESPONSE_INVOKE)
        self.set_default_response(Gtk.ResponseType.CANCEL)
コード例 #30
0
ファイル: __init__.py プロジェクト: yaoml/quodlibet
def format_time_long(time, limit=2):
    """Turn a time value in seconds into x hours, x minutes, etc.

    `limit` limits the count of units used, so the result will be <= time.
    0 means no limit.
    """

    from quodlibet import ngettext

    if time < 1:
        return _("No time information")

    cutoffs = [
        (60, lambda n: ngettext("%d second", "%d seconds", n)),
        (60, lambda n: ngettext("%d minute", "%d minutes", n)),
        (24, lambda n: ngettext("%d hour", "%d hours", n)),
        (365, lambda n: ngettext("%d day", "%d days", n)),
        (None, lambda n: ngettext("%d year", "%d years", n)),
    ]

    time_str = []
    for divisor, gettext_partial in cutoffs:
        if time < 1:
            break
        if divisor is None:
            time, unit = 0, time
        else:
            time, unit = divmod(time, divisor)
        if unit:
            time_str.append(gettext_partial(unit) % unit)
    time_str.reverse()

    if limit:
        time_str = time_str[:limit]

    return ", ".join(time_str)
コード例 #31
0
ファイル: properties.py プロジェクト: John-Peters/quodlibet
    def __on_changed(self, widget, songs):
        if songs:
            if len(songs) == 1:
                title = songs[0].comma("title")
            else:
                title = ngettext(
                    "%(title)s and %(count)d more",
                    "%(title)s and %(count)d more",
                    len(songs) - 1) % {'title': songs[0].comma("title"),
                                       'count': len(songs) - 1}
            self.set_title("%s - %s" % (title, _("Properties")))
        else:
            self.set_title(_("Properties"))

        self.set_pending(None)
コード例 #32
0
ファイル: __init__.py プロジェクト: ZDBioHazard/quodlibet
def format_time_long(time, limit=2):
    """Turn a time value in seconds into x hours, x minutes, etc.

    `limit` limits the count of units used, so the result will be <= time.
    0 means no limit.
    """

    from quodlibet import ngettext

    if time < 1:
        return _("No time information")

    cutoffs = [
        (60, lambda n: ngettext("%d second", "%d seconds", n)),
        (60, lambda n: ngettext("%d minute", "%d minutes", n)),
        (24, lambda n: ngettext("%d hour", "%d hours", n)),
        (365, lambda n: ngettext("%d day", "%d days", n)),
        (None, lambda n: ngettext("%d year", "%d years", n)),
    ]

    time_str = []
    for divisor, gettext_partial in cutoffs:
        if time < 1:
            break
        if divisor is None:
            time, unit = 0, time
        else:
            time, unit = divmod(time, divisor)
        if unit:
            time_str.append(gettext_partial(unit) % unit)
    time_str.reverse()

    if limit:
        time_str = time_str[:limit]

    return ", ".join(time_str)
コード例 #33
0
ファイル: playlist.py プロジェクト: ZDBioHazard/quodlibet
    def __init__(self, parent, plugin_name, count):
        params = {"name": plugin_name, "count": format_int_locale(count)}
        title = ngettext("Run the plugin \"%(name)s\" on %(count)s playlist?",
                         "Run the plugin \"%(name)s\" on %(count)s playlists?",
                         count) % params

        super(ConfirmMultiPlaylistInvoke, self).__init__(
            get_top_parent(parent),
            title, "",
            buttons=Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(
            _("_Run Plugin"), Icons.SYSTEM_RUN, self.RESPONSE_INVOKE)
        self.set_default_response(Gtk.ResponseType.CANCEL)
コード例 #34
0
    def __popup(self, view, library):
        albums = self.__get_selected_albums()
        songs = self.__get_songs_from_albums(albums)

        items = []
        if self.__cover_column.get_visible():
            num = len(albums)
            button = MenuItem(
                ngettext("Reload album _cover", "Reload album _covers", num),
                Icons.VIEW_REFRESH)
            button.connect('activate', self.__refresh_album, view)
            items.append(button)

        menu = SongsMenu(library, songs, items=[items])
        menu.show_all()
        return view.popup_menu(menu, 0, Gtk.get_current_event_time())
コード例 #35
0
ファイル: main.py プロジェクト: urielz/quodlibet
    def __popup(self, view, library):
        albums = self.__get_selected_albums()
        songs = self.__get_songs_from_albums(albums)

        items = []
        if self.__cover_column.get_visible():
            num = len(albums)
            button = MenuItem(
                ngettext("Reload album _cover", "Reload album _covers", num),
                Icons.VIEW_REFRESH)
            button.connect('activate', self.__refresh_album, view)
            items.append(button)

        menu = SongsMenu(library, songs, items=[items])
        menu.show_all()
        return view.popup_menu(menu, 0, Gtk.get_current_event_time())
コード例 #36
0
ファイル: main.py プロジェクト: urielz/quodlibet
        def cell_data(view, cell, model, iter_, data):
            album = model.get_album(iter_)

            if album is None:
                text = "<b>%s</b>" % _("All Albums")
                text += "\n" + ngettext("%d album", "%d albums",
                        len(model) - 1) % (len(model) - 1)
                markup = text
            else:
                markup = self.display_pattern % album

            if self.__last_render == markup:
                return
            self.__last_render = markup
            cell.markup = markup
            cell.set_property('markup', markup)
コード例 #37
0
ファイル: main.py プロジェクト: tralph3/quodlibet
        def cell_data(view, cell, model, iter_, data):
            album = model.get_album(iter_)

            if album is None:
                text = "<b>%s</b>" % _("All Albums")
                text += "\n" + ngettext("%d album", "%d albums",
                        len(model) - 1) % (len(model) - 1)
                markup = text
            else:
                markup = self.display_pattern % album

            if self.__last_render == markup:
                return
            self.__last_render = markup
            cell.markup = markup
            cell.set_property('markup', markup)
コード例 #38
0
ファイル: main.py プロジェクト: WammKD/quodlibet
    def __popup(self, view, library):

        albums = self.__get_selected_albums()
        songs = self.__get_songs_from_albums(albums)

        items = []
        num = len(albums)
        button = MenuItem(
            ngettext("Reload album _cover", "Reload album _covers", num),
            Icons.VIEW_REFRESH)
        button.connect('activate', self.__refresh_album, view)
        items.append(button)

        menu = SongsMenu(library, songs, items=[items])
        menu.show_all()
        popup_menu_at_widget(menu, view, Gdk.BUTTON_SECONDARY,
                             Gtk.get_current_event_time())
コード例 #39
0
    def __init__(self, parent, plugin_name, count):
        params = {"name": plugin_name, "count": format_int_locale(count)}
        title = ngettext(
            "Run the plugin \"%(name)s\" on %(count)s playlist?",
            "Run the plugin \"%(name)s\" on %(count)s playlists?",
            count) % params

        super(ConfirmMultiPlaylistInvoke,
              self).__init__(get_top_parent(parent),
                             title,
                             "",
                             buttons=Gtk.ButtonsType.NONE)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Run Plugin"), Icons.SYSTEM_RUN,
                             self.RESPONSE_INVOKE)
        self.set_default_response(Gtk.ResponseType.CANCEL)
コード例 #40
0
ファイル: information.py プロジェクト: urielz/quodlibet
    def _album(self, songs, box):
        noalbum = 0
        albums = {}
        for song in songs:
            if "album" in song:
                albums[song.list("album")[0]] = song
            else:
                noalbum += 1
        albums = [(song.get("date"), song, album) for
                  album, song in albums.items()]
        albums.sort()

        def format(args):
            date, song, album = args
            if date:
                return "%s (%s)" % (album, date[:4])
            else:
                return album

        get_cover = app.cover_manager.get_cover
        covers = [(a, get_cover(s), s) for d, s, a in albums]
        albums = map(format, albums)
        if noalbum:
            albums.append(ngettext("%d song with no album",
                "%d songs with no album", noalbum) % noalbum)
        l = Label("\n".join(albums))
        l.set_ellipsize(Pango.EllipsizeMode.END)
        box.pack_start(Frame(_("Selected Discography"), l), False, False, 0)

        covers = [ac for ac in covers if bool(ac[1])]
        t = Gtk.Table(n_rows=4, n_columns=(len(covers) // 4) + 1)
        t.set_col_spacings(12)
        t.set_row_spacings(12)
        added = set()
        for i, (album, cover, song) in enumerate(covers):
            if cover.name in added:
                continue
            cov = CoverImage(song=song)
            cov.get_child().set_tooltip_text(album)
            c = i % 4
            r = i // 4
            t.attach(cov, c, c + 1, r, r + 1,
                     xoptions=Gtk.AttachOptions.EXPAND, yoptions=0)
            added.add(cover.name)
        box.pack_start(t, True, True, 0)
コード例 #41
0
    def _people(self, songs, box):
        artists = set()
        none = 0
        for song in songs:
            if "artist" in song:
                artists.update(song.list("artist"))
            else:
                none += 1
        artists = sorted(artists)
        num_artists = len(artists)

        if none:
            artists.append(ngettext("%d song with no artist",
                                    "%d songs with no artist", none) % none)
        label = Label(markup=util.escape("\n".join(artists)), ellipsize=True)
        frame = Frame("%s (%d)" % (util.capitalize(_("artists")), num_artists),
                      label)
        box.pack_start(frame, False, False, 0)
コード例 #42
0
ファイル: main.py プロジェクト: urielz/quodlibet
 def _show_tooltip(self, widget, x, y, keyboard_tip, tooltip):
     w = self.scrollwin.get_hadjustment().get_value()
     z = self.scrollwin.get_vadjustment().get_value()
     path = widget.get_path_at_pos(int(x + w), int(y + z))
     if path is None:
         return False
     model = widget.get_model()
     iter = model.get_iter(path)
     album = model.get_album(iter)
     if album is None:
         text = "<b>%s</b>" % _("All Albums")
         text += "\n" + ngettext("%d album",
             "%d albums", len(model) - 1) % (len(model) - 1)
         markup = text
     else:
         markup = self.display_pattern % album
     tooltip.set_markup(markup)
     return True
コード例 #43
0
ファイル: information.py プロジェクト: urielz/quodlibet
    def _album(self, songs, box):
        albums = set()
        none = 0
        for song in songs:
            if "album" in song:
                albums.update(song.list("album"))
            else:
                none += 1
        albums = sorted(albums)
        num_albums = len(albums)

        if none:
            albums.append(ngettext("%d song with no album",
                                   "%d songs with no album", none) % none)
        box.pack_start(Frame(
            "%s (%d)" % (util.capitalize(_("albums")), num_albums),
            Label("\n".join(albums))),
                        False, False, 0)
コード例 #44
0
ファイル: main.py プロジェクト: tralph3/quodlibet
 def _show_tooltip(self, widget, x, y, keyboard_tip, tooltip):
     w = self.scrollwin.get_hadjustment().get_value()
     z = self.scrollwin.get_vadjustment().get_value()
     path = widget.get_path_at_pos(int(x + w), int(y + z))
     if path is None:
         return False
     model = widget.get_model()
     iter = model.get_iter(path)
     album = model.get_album(iter)
     if album is None:
         text = "<b>%s</b>" % _("All Albums")
         text += "\n" + ngettext("%d album",
             "%d albums", len(model) - 1) % (len(model) - 1)
         markup = text
     else:
         markup = self.display_pattern % album
     tooltip.set_markup(markup)
     return True
コード例 #45
0
    def _album(self, songs, box):
        albums = set()
        none = 0
        for song in songs:
            if "album" in song:
                albums.update(song.list("album"))
            else:
                none += 1
        albums = sorted(albums)
        num_albums = len(albums)

        if none:
            albums.append(
                ngettext("%d song with no album", "%d songs with no album",
                         none) % none)
        box.pack_start(
            Frame("%s (%d)" % (util.capitalize(_("albums")), num_albums),
                  Label("\n".join(albums))), False, False, 0)
コード例 #46
0
ファイル: information.py プロジェクト: elfalem/quodlibet
    def _people(self, songs, box):
        artists = set()
        none = 0
        for song in songs:
            if "artist" in song:
                artists.update(song.list("artist"))
            else:
                none += 1
        artists = sorted(artists)
        num_artists = len(artists)

        if none:
            artists.append(ngettext("%d song with no artist",
                                    "%d songs with no artist", none) % none)
        label = Label(markup=util.escape("\n".join(artists)), ellipsize=True)
        frame = Frame("%s (%d)" % (util.capitalize(_("artists")), num_artists),
                      label)
        box.pack_start(frame, False, False, 0)
コード例 #47
0
ファイル: main.py プロジェクト: LudoBike/quodlibet
    def __popup(self, view, library):

        albums = self.__get_selected_albums()
        songs = self.__get_songs_from_albums(albums)

        items = []
        num = len(albums)
        button = MenuItem(
            ngettext("Reload album _cover", "Reload album _covers", num),
            Icons.VIEW_REFRESH)
        button.connect('activate', self.__refresh_album, view)
        items.append(button)

        menu = SongsMenu(library, songs, items=[items])
        menu.show_all()
        popup_menu_at_widget(menu, view,
            Gdk.BUTTON_SECONDARY,
            Gtk.get_current_event_time())
コード例 #48
0
 def __remove(self, view) -> None:
     selection = self.view.get_selection()
     model, paths = selection.get_selected_rows()
     gone_dirs = [model[p][0] for p in paths or []]
     total = len(gone_dirs)
     if not total:
         return
     msg = (_("Remove {dir!r} and all its tracks?").format(
         dir=gone_dirs[0]) if total == 1 else
            _("Remove {n} library paths and their tracks?").format(n=total))
     title = ngettext("Remove library path?", "Remove library paths?",
                      total)
     prompt = ConfirmationPrompt(self,
                                 title,
                                 msg,
                                 _("Remove"),
                                 ok_button_icon=Icons.LIST_REMOVE)
     if prompt.run() == ConfirmationPrompt.RESPONSE_INVOKE:
         view.remove_selection()
         self.__save()
コード例 #49
0
            def download_cb(menu_item):
                songs = relevant
                total = len(songs)
                msg = ngettext("Download {name!r} to",
                               "Download {total} files to", total)
                msg = msg.format(
                    name=next(iter(songs))("title")[:99] if total else "?",
                    total=total)
                chooser = folder_chooser or choose_folders
                paths = chooser(None,
                                msg,
                                _("Download here"),
                                allow_multiple=False)
                if not paths:
                    print_d("Cancelling download")
                    return
                path = paths[0]
                progress = DownloadProgress(songs)

                progress.connect('finished', _finished)
                copool.add(progress.download_songs, path)
コード例 #50
0
ファイル: exfalsowindow.py プロジェクト: zsau/quodlibet
    def __changed(self, selector, selection, label):
        model, rows = selection.get_selected_rows()
        files = []

        if len(rows) < 2:
            count = len(model or [])
        else:
            count = len(rows)
        label.set_text(numeric_phrase("%d song", "%d songs", count))

        for row in rows:
            filename = model[row][0]
            if not os.path.exists(filename):
                pass
            elif filename in self.__library:
                song = self.__library[filename]
                if song("~#mtime") + 1. < mtime(filename):
                    try:
                        song.reload()
                    except AudioFileError:
                        pass
                files.append(song)
            else:
                files.append(formats.MusicFile(filename))
        files = list(filter(None, files))
        if len(files) == 0:
            self.set_title("Ex Falso")
        elif len(files) == 1:
            self.set_title("%s - Ex Falso" % files[0].comma("title"))
        else:
            params = ({'title': files[0].comma("title"),
                       'count': format_int_locale(len(files) - 1)})
            self.set_title(
                "%s - Ex Falso" %
                (ngettext("%(title)s and %(count)s more",
                          "%(title)s and %(count)s more", len(files) - 1)
                 % params))
        self.__library.add(files)
        self.emit('changed', files)
コード例 #51
0
ファイル: information.py プロジェクト: darthoctopus/quodlibet
    def _album(self, songs, box):
        albums = set()
        none = 0
        for song in songs:
            if "album" in song:
                albums.update(song.list("album"))
            else:
                none += 1
        albums = sorted(albums)
        num_albums = len(albums)

        markup = "\n".join("<i>%s</i>" % util.escape(a) for a in albums)
        if none:
            text = ngettext("%d song with no album", "%d songs with no album",
                            none) % none
            markup += "\n%s" % util.escape(text)

        label = Label()
        label.set_markup(markup)
        box.pack_start(
            Frame("%s (%d)" % (util.capitalize(_("albums")), num_albums),
                  label), False, False, 0)
コード例 #52
0
    def __changed(self, selector, selection, label):
        model, rows = selection.get_selected_rows()
        files = []

        if len(rows) < 2:
            count = len(model or [])
        else:
            count = len(rows)
        label.set_text(numeric_phrase("%d song", "%d songs", count))

        for row in rows:
            filename = model[row][0]
            if not os.path.exists(filename):
                pass
            elif filename in self.__library:
                song = self.__library[filename]
                if song("~#mtime") + 1. < mtime(filename):
                    try:
                        song.reload()
                    except AudioFileError:
                        pass
                files.append(song)
            else:
                files.append(formats.MusicFile(filename))
        files = list(filter(None, files))
        if len(files) == 0:
            self.set_title("Ex Falso")
        elif len(files) == 1:
            self.set_title("%s - Ex Falso" % files[0].comma("title"))
        else:
            params = ({
                'title': files[0].comma("title"),
                'count': format_int_locale(len(files) - 1)
            })
            self.set_title("%s - Ex Falso" % (ngettext(
                "%(title)s and %(count)s more", "%(title)s and %(count)s more",
                len(files) - 1) % params))
        self.__library.add(files)
        self.emit('changed', files)
コード例 #53
0
ファイル: main.py プロジェクト: urielz/quodlibet
    def __popup(self, view, event, library):
        x = int(event.x)
        y = int(event.y)
        current_path = view.get_path_at_pos(x, y)
        if event.button == Gdk.BUTTON_SECONDARY and current_path:
            if not view.path_is_selected(current_path):
                view.unselect_all()
            view.select_path(current_path)
            albums = self.__get_selected_albums()
            songs = self.__get_songs_from_albums(albums)

            items = []
            num = len(albums)
            button = MenuItem(
                ngettext("Reload album _cover", "Reload album _covers", num),
                Icons.VIEW_REFRESH)
            button.connect('activate', self.__refresh_album, view)
            items.append(button)

            menu = SongsMenu(library, songs, items=[items])
            menu.show_all()
            menu.popup(None, None, None, event.button, event.time,
                Gtk.get_current_event_time())
コード例 #54
0
ファイル: information.py プロジェクト: elfalem/quodlibet
    def _album(self, songs, box):
        albums = set()
        none = 0
        for song in songs:
            if "album" in song:
                albums.update(song.list("album"))
            else:
                none += 1
        albums = sorted(albums)
        num_albums = len(albums)

        markup = "\n".join("<i>%s</i>" % util.escape(a) for a in albums)
        if none:
            text = ngettext("%d song with no album",
                            "%d songs with no album",
                            none) % none
            markup += "\n%s" % util.escape(text)

        label = Label()
        label.set_markup(markup)
        box.pack_start(Frame(
            "%s (%d)" % (util.capitalize(_("albums")), num_albums),
            label), False, False, 0)
コード例 #55
0
ファイル: __init__.py プロジェクト: ZDBioHazard/quodlibet
def format_time_seconds(time):
    from quodlibet import ngettext

    time_str = locale.format("%d", time, grouping=True)
    return ngettext("%s second", "%s seconds", time) % time_str
コード例 #56
0
ファイル: __init__.py プロジェクト: elfalem/quodlibet
def format_time_seconds(time):
    from quodlibet import ngettext

    time_str = format_int_locale(time)
    return ngettext("%s second", "%s seconds", time) % time_str
コード例 #57
0
ファイル: collection.py プロジェクト: ZDBioHazard/quodlibet
 def __str__(self):
     songs_text = (ngettext("%d song", "%d songs", len(self.songs))
                   % len(self.songs))
     return u"\"%s\" (%s)" % (self.name, songs_text)
コード例 #58
0
ファイル: collection.py プロジェクト: ZDBioHazard/quodlibet
    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({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 NUMERIC_ZERO_DEFAULT:
                return 0
            return None
        elif key[:1] == "~":
            key = key[1:]
            numkey = key.split(":")[0]
            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 numkey == "length":
                length = self.__get_value("~#" + key)
                return None if length is None else util.format_time(length)
            elif numkey == "long-length":
                length = self.__get_value("~#" + key[5:])
                return (None if length is None
                        else util.format_time_long(length))
            elif numkey == "tracks":
                tracks = self.__get_value("~#" + key)
                return (None if tracks is None else
                        ngettext("%d track", "%d tracks", tracks) % tracks)
            elif numkey == "discs":
                discs = self.__get_value("~#" + key)
                if discs > 1:
                    return ngettext("%d disc", "%d discs", discs) % discs
                else:
                    # TODO: check this is correct for discs == 1
                    return None
            elif numkey == "rating":
                rating = self.__get_value("~#" + key)
                if rating is None:
                    return None
                return util.format_rating(rating)
            elif numkey == "filesize":
                size = self.__get_value("~#" + key)
                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 = listmap(lambda x: x[0],
                     sorted(result.items(), key=lambda x: (x[1], x[0])))
        return "\n".join(values) if values else None
コード例 #59
0
ファイル: replaygain.py プロジェクト: Muges/quodlibet
    def __init__(self, albums, parent, process_mode):
        super(RGDialog, self).__init__(
            title=_('ReplayGain Analyzer'), parent=parent)

        self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
        self.add_icon_button(_("_Save"), Icons.DOCUMENT_SAVE,
                             Gtk.ResponseType.OK)

        self.process_mode = process_mode
        self.set_default_size(600, 400)
        self.set_border_width(6)

        hbox = Gtk.HBox(spacing=6)
        info = Gtk.Label()
        hbox.pack_start(info, True, True, 0)
        self.vbox.pack_start(hbox, False, False, 6)

        swin = Gtk.ScrolledWindow()
        swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        swin.set_shadow_type(Gtk.ShadowType.IN)

        self.vbox.pack_start(swin, True, True, 0)
        view = HintedTreeView()
        swin.add(view)

        def icon_cdf(column, cell, model, iter_, *args):
            item = model[iter_][0]
            if item.error:
                cell.set_property('icon-name', Icons.DIALOG_ERROR)
            else:
                cell.set_property('icon-name', Icons.NONE)

        column = Gtk.TreeViewColumn()
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
        icon_render = Gtk.CellRendererPixbuf()
        column.pack_start(icon_render, True)
        column.set_cell_data_func(icon_render, icon_cdf)
        view.append_column(column)

        def track_cdf(column, cell, model, iter_, *args):
            item = model[iter_][0]
            cell.set_property('text', item.title)
            cell.set_sensitive(model[iter_][1])

        column = Gtk.TreeViewColumn(_("Track"))
        column.set_expand(True)
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
        track_render = Gtk.CellRendererText()
        track_render.set_property('ellipsize', Pango.EllipsizeMode.END)
        column.pack_start(track_render, True)
        column.set_cell_data_func(track_render, track_cdf)
        view.append_column(column)

        def progress_cdf(column, cell, model, iter_, *args):
            item = model[iter_][0]
            cell.set_property('value', int(item.progress * 100))
            cell.set_sensitive(model[iter_][1])

        column = Gtk.TreeViewColumn(_("Progress"))
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
        progress_render = Gtk.CellRendererProgress()
        column.pack_start(progress_render, True)
        column.set_cell_data_func(progress_render, progress_cdf)
        view.append_column(column)

        def gain_cdf(column, cell, model, iter_, *args):
            item = model[iter_][0]
            if item.gain is None or not item.done:
                cell.set_property('text', "-")
            else:
                cell.set_property('text', "%.2f db" % item.gain)
            cell.set_sensitive(model[iter_][1])

        column = Gtk.TreeViewColumn(_("Gain"))
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
        gain_renderer = Gtk.CellRendererText()
        column.pack_start(gain_renderer, True)
        column.set_cell_data_func(gain_renderer, gain_cdf)
        view.append_column(column)

        def peak_cdf(column, cell, model, iter_, *args):
            item = model[iter_][0]
            if item.gain is None or not item.done:
                cell.set_property('text', "-")
            else:
                cell.set_property('text', "%.2f" % item.peak)
            cell.set_sensitive(model[iter_][1])

        column = Gtk.TreeViewColumn(_("Peak"))
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
        peak_renderer = Gtk.CellRendererText()
        column.pack_start(peak_renderer, True)
        column.set_cell_data_func(peak_renderer, peak_cdf)
        view.append_column(column)

        self.create_pipelines()
        self._timeout = None
        self._sigs = {}
        self._done = []

        self.__fill_view(view, albums)
        num_to_process = sum(int(rga.should_process) for rga in self._todo)
        template = ngettext(
            "There is <b>%(to-process)s</b> album to update (of %(all)s)",
            "There are <b>%(to-process)s</b> albums to update (of %(all)s)",
            num_to_process)
        info.set_markup(template % {
            "to-process": format_int_locale(num_to_process),
            "all": format_int_locale(len(self._todo)),
        })
        self.connect("destroy", self.__destroy)
        self.connect('response', self.__response)