示例#1
0
    def restore(self):
        text = config.gettext("browsers", "query_text")
        entry = self.__search
        entry.set_text(text)

        # update_filter expects a parsable query
        if Query.is_parsable(text):
            self.__update_filter(entry, text, scroll_up=False, restore=True)

        keys = config.gettext("browsers", "albums").split("\n")

        # FIXME: If albums is "" then it could be either all albums or
        # no albums. If it's "" and some other stuff, assume no albums,
        # otherwise all albums.
        self.__inhibit()
        if keys == [""]:
            self.view.set_cursor((0,))
        else:

            def select_fun(row):
                album = row[0].album
                if not album:  # all
                    return False
                return album.str_key in keys
            self.view.select_by_func(select_fun)
        self.__uninhibit()
示例#2
0
    def restore(self):
        try:
            text = config.gettext("browsers", "query_text")
        except config.Error:
            pass
        else:
            self._set_text(text)

        selected = config.gettext("browsers", "pane_selection")
        if not selected:
            return

        for pane, string in zip(self._panes, selected.split(u"\n")):
            pane.parse_restore_string(string)
示例#3
0
    def _apply_value(self, model, iter_, cell, stamp):
        if not stamp:
            cell.set_property('text', _("Never"))
        else:
            try:
                date = datetime.datetime.fromtimestamp(stamp).date()
            except (OverflowError, ValueError, OSError):
                text = u""
            else:
                format_setting = config.gettext("settings",
                                      "datecolumn_timestamp_format")

                # use format configured in Advanced Preferences
                if format_setting:
                    format_ = format_setting
                # use default behaviour-format
                else:
                    today = datetime.datetime.now().date()
                    days = (today - date).days
                    if days == 0:
                        format_ = "%X"
                    elif days < 7:
                        format_ = "%A"
                    else:
                        format_ = "%x"

                stamp = time.localtime(stamp)
                text = time.strftime(format_, stamp)
            cell.set_property('text', text)
示例#4
0
 def __init__(self, tag, value):
     super(SplitValues, self).__init__(
         label=_("Split into _Multiple Values"), use_underline=True)
     self.set_image(Gtk.Image.new_from_icon_name(
         Icons.EDIT_FIND_REPLACE, Gtk.IconSize.MENU))
     spls = config.gettext("editing", "split_on").split()
     self.set_sensitive(len(split_value(value, spls)) > 1)
示例#5
0
 def __init__(self, tag, value):
     super(SplitTitle, self).__init__(
         label=_("Split _Version out of Title"), use_underline=True)
     self.set_image(Gtk.Image.new_from_icon_name(
         Icons.EDIT_FIND_REPLACE, Gtk.IconSize.MENU))
     spls = config.gettext("editing", "split_on").split()
     self.set_sensitive(bool(split_title(value, spls)[1]))
示例#6
0
    def __init__(self, player):
        super(VolumeMenu, self).__init__()

        # ubuntu 12.04..
        if hasattr(player, "bind_property"):
            # Translators: player state, no action
            item = Gtk.CheckMenuItem(label=_("_Mute"), use_underline=True)
            player.bind_property("mute", item, "active",
                                 GObject.BindingFlags.BIDIRECTIONAL)
            self.append(item)
            item.show()

        item = Gtk.MenuItem(label=_("_Replay Gain Mode"), use_underline=True)
        self.append(item)
        item.show()

        # Set replaygain mode as saved in configuration
        replaygain_mode = config.gettext("player", "replaygain_mode", "auto")
        self.__set_mode(player, replaygain_mode)

        rg = Gtk.Menu()
        rg.show()
        item.set_submenu(rg)
        item = None
        for mode, title, profile in self.__modes:
            item = RadioMenuItem(group=item, label=title,
                                 use_underline=True)
            rg.append(item)
            item.connect("toggled", self.__changed, player, mode)
            if replaygain_mode == mode:
                item.set_active(True)
            item.show()
示例#7
0
文件: main.py 项目: zsau/quodlibet
    def refresh_panes(self):
        self.multi_paned.destroy()

        # Fill in the pane list. The last pane reports back to us.
        self._panes = [self]
        for header in reversed(get_headers()):
            pane = Pane(self._library, header, self._panes[0])
            pane.connect('row-activated',
                         lambda *x: self.songs_activated())
            self._panes.insert(0, pane)
        self._panes.pop()  # remove self

        # Put the panes in scrollable windows
        sws = []
        for pane in self._panes:
            sw = ScrolledWindow()
            sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
            sw.set_shadow_type(Gtk.ShadowType.IN)
            sw.add(pane)
            sws.append(sw)

        self.multi_paned.set_widgets(sws)
        self.multi_paned.show_all()
        self.main_box.pack1(self.multi_paned.get_paned(), True, False)

        self.__star = {}
        for p in self._panes:
            tags = [t for t in p.tags if not t.startswith("~#")]
            self.__star.update(dict.fromkeys(tags))

        self.set_column_mode(config.gettext("browsers", "pane_mode"))
示例#8
0
def _init_gettext(no_translations=False):
    """Call before using gettext helpers"""

    if no_translations:
        language = u"C"
    else:
        language = config.gettext("settings", "language")
        if not language:
            language = None

    i18n.init(language)

    # Use the locale dir in ../build/share/locale if there is one
    base_dir = get_base_dir()
    localedir = os.path.dirname(base_dir)
    localedir = os.path.join(localedir, "build", "share", "locale")
    if not os.path.isdir(localedir) and os.name == "nt":
        # py2exe case
        localedir = os.path.join(
            base_dir, "..", "..", "share", "locale")

    i18n.register_translation("quodlibet", localedir)
    debug_text = environ.get("QUODLIBET_TEST_TRANS")
    if debug_text is not None:
        i18n.set_debug_text(fsn2text(debug_text))
示例#9
0
def background_filter():
    bg = config.gettext("browsers", "background")
    if not bg:
        return
    try:
        return Query(bg, SongList.star).search
    except Query.error:
        pass
示例#10
0
 def __update_title(self, player):
     song = player.info
     title = "Quod Libet"
     if song:
         tag = config.gettext("settings", "window_title_pattern")
         if tag:
             title = song.comma(tag) + " - " + title
     self.set_title(title)
示例#11
0
    def PluginPreferences(self, *args):

        current = config.gettext("settings", "language")
        if not current:
            current = None

        combo = Gtk.ComboBox()
        model = ObjectStore()
        combo.set_model(model)
        for lang_id in ([None] + sorted(get_available_languages("quodlibet"))):
            iter_ = model.append(row=[lang_id])
            if lang_id == current:
                combo.set_active_iter(iter_)

        def cell_func(combo, render, model, iter_, *args):
            value = model.get_value(iter_)
            if value is None:
                text = escape(_("System Default"))
            else:
                if value == u"C":
                    value = u"en"
                text = "%s <span weight='light'>(%s)</span>" % (
                    escape(value),
                    escape(iso639.translate(value.split("_", 1)[0])))
            render.set_property("markup", text)

        render = Gtk.CellRendererText()
        render.props.ellipsize = Pango.EllipsizeMode.END
        combo.pack_start(render, True)
        combo.set_cell_data_func(render, cell_func)

        def on_combo_changed(combo):
            new_language = model.get_value(combo.get_active_iter())
            if new_language is None:
                new_language = u""
            config.settext("settings", "language", new_language)

        combo.connect("changed", on_combo_changed)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
        box.pack_start(combo, False, False, 0)
        box.pack_start(
            Gtk.Label(
                label=_(
                    "A restart is required for any changes to take effect"),
                wrap=True,
                xalign=0),
            False, False, 0)

        return box
示例#12
0
def background_filter():
    """Returns a filter function for AudioFile or None if nothing should be
    filtered.

    The filter is meant to be used globally to hide songs from the main
    library.

    Returns:
        function or None
    """

    bg = config.gettext("browsers", "background")
    if not bg:
        return
    query = Query(bg, SongList.star)
    if query.is_parsable:
        return query.search
示例#13
0
文件: prefs.py 项目: zsau/quodlibet
    def __init__(self, browser):
        super(ColumnModes, self).__init__(spacing=6)
        self.browser = browser
        self.buttons = []

        group = None
        for mode in [COLUMN_MODE_SMALL, COLUMN_MODE_WIDE,
                     COLUMN_MODE_COLUMNAR]:
            group = Gtk.RadioButton(group=group, label=_(mode))
            if mode == config.gettext("browsers", "pane_mode"):
                group.set_active(True)
            self.pack_start(group, False, True, 0)
            self.buttons.append(group)

        # Connect to signal after the correct radio button has been
        # selected
        for button in self.buttons:
            button.connect('toggled', self.toggled)
def _config(section, option, label, tooltip, getter):
    def on_changed(entry, *args):
        config.settext(section, option, gdecode(entry.get_text()))

    entry = UndoEntry()
    entry.set_tooltip_text(tooltip)
    entry.set_text(config.gettext(section, option))
    entry.connect("changed", on_changed)

    def on_reverted(*args):
        config.reset(section, option)
        entry.set_text(config.gettext(section, option))

    revert = Gtk.Button()
    revert.add(Gtk.Image.new_from_icon_name(
        Icons.DOCUMENT_REVERT, Gtk.IconSize.BUTTON))
    revert.connect("clicked", on_reverted)

    return (Gtk.Label(label=label), entry, revert)
示例#15
0
    def restore(self):
        text = config.gettext("browsers", "query_text")
        self.__searchbar.set_text(text)
        if Query.is_parsable(text):
            self.__filter_changed(self.__searchbar, text, restore=True)

        keys = config.get("browsers", "radio").splitlines()

        def select_func(row):
            return row[self.TYPE] != self.TYPE_SEP and row[self.KEY] in keys

        self.__inhibit()
        view = self.view
        if not view.select_by_func(select_func):
            for row in view.get_model():
                if row[self.TYPE] == self.TYPE_FAV:
                    view.set_cursor(row.path)
                    break
        self.__uninhibit()
示例#16
0
 def activated(self, tag, value):
     spls = config.gettext("editing", "split_on").split()
     artist, others = split_people(value, spls)
     return [(tag, artist)] + [(self.needs[0], o) for o in others]
示例#17
0
 def activated(self, tag, value):
     spls = config.gettext("editing", "split_on").split()
     title, versions = split_title(value, spls)
     return [(tag, title)] + [("version", v) for v in versions]
示例#18
0
    def __call__(self, key, default: Any = u"", connector=" - ", joiner=', '):
        """Return the value(s) for a key, synthesizing if necessary.
        Multiple values for a key are delimited by newlines.

        A default value may be given (like `dict.get`);
        the default default is an empty unicode string
        (even if the tag is numeric).

        If a tied tag ('a~b') is requested, the `connector` keyword
        argument may be used to specify what it is tied with.
        In case the tied tag contains numeric and file path tags, the result
        will still be a unicode string.
        The `joiner` keyword specifies how multiple *values* will be joined
        within that tied tag output, e.g.
            ~people~title = "Kanye West, Jay Z - New Day"

        For details on tied tags, see the documentation for `util.tagsplit`.
        """

        if key[:1] == "~":
            key = key[1:]
            if "~" in key:
                real_key = "~" + key
                values = []
                sub_tags = util.tagsplit(real_key)
                # If it's genuinely a tied tag (not ~~people etc), we want
                # to delimit the multi-values separately from the tying
                j = joiner if len(sub_tags) > 1 else "\n"
                for t in sub_tags:
                    vs = [decode_value(real_key, v) for v in (self.list(t))]
                    v = j.join(vs)
                    if v:
                        values.append(v)
                return connector.join(values) or default
            elif key == "#track":
                try:
                    return int(self["tracknumber"].split("/")[0])
                except (ValueError, TypeError, KeyError):
                    return default
            elif key == "#disc":
                try:
                    return int(self["discnumber"].split("/")[0])
                except (ValueError, TypeError, KeyError):
                    return default
            elif key == "length":
                length = self.get("~#length")
                if length is None:
                    return default
                else:
                    return util.format_time_display(length)
            elif key == "#rating":
                return dict.get(self, "~" + key, config.RATINGS.default)
            elif key == "rating":
                return util.format_rating(self("~#rating"))
            elif key == "people":
                return "\n".join(self.list_unique(PEOPLE)) or default
            elif key == "people:real":
                # Issue 1034: Allow removal of V.A. if others exist.
                unique = self.list_unique(PEOPLE)
                # Order is important, for (unlikely case): multiple removals
                for val in VARIOUS_ARTISTS_VALUES:
                    if len(unique) > 1 and val in unique:
                        unique.remove(val)
                return "\n".join(unique) or default
            elif key == "people:roles":
                return (self._role_call("performer", PEOPLE) or default)
            elif key == "peoplesort":
                return ("\n".join(self.list_unique(PEOPLE_SORT))
                        or self("~people", default, connector))
            elif key == "peoplesort:roles":
                # Ignores non-sort tags if there are any sort tags (e.g. just
                # returns "B" for {artist=A, performersort=B}).
                # TODO: figure out the "correct" behavior for mixed sort tags
                return (self._role_call("performersort", PEOPLE_SORT)
                        or self("~peoplesort", default, connector))
            elif key in ("performers", "performer"):
                return self._prefixvalue("performer") or default
            elif key in ("performerssort", "performersort"):
                return (self._prefixvalue("performersort")
                        or self("~" + key[-4:], default, connector))
            elif key in ("performers:roles", "performer:roles"):
                return (self._role_call("performer") or default)
            elif key in ("performerssort:roles", "performersort:roles"):
                return (self._role_call("performersort") or self(
                    "~" + key.replace("sort", ""), default, connector))
            elif key == "basename":
                return os.path.basename(self["~filename"]) or self["~filename"]
            elif key == "dirname":
                return os.path.dirname(self["~filename"]) or self["~filename"]
            elif key == "uri":
                try:
                    return self["~uri"]
                except KeyError:
                    return fsn2uri(self["~filename"])
            elif key == "format":
                return self.get("~format", str(self.format))
            elif key == "codec":
                codec = self.get("~codec")
                if codec is None:
                    return self("~format")
                return codec
            elif key == "encoding":
                encoding = "\n".join(
                    part
                    for part in [self.get("~encoding"),
                                 self.get("encodedby")] if part)
                return encoding or default
            elif key == "language":
                codes = self.list("language")
                if not codes:
                    return default
                return u"\n".join(iso639.translate(c) or c for c in codes)
            elif key == "bitrate":
                return util.format_bitrate(self("~#bitrate"))
            elif key == "#date":
                date = self.get("date")
                if date is None:
                    return default
                return util.date_key(date)
            elif key == "year":
                return self.get("date", default)[:4]
            elif key == "#year":
                try:
                    return int(self.get("date", default)[:4])
                except (ValueError, TypeError, KeyError):
                    return default
            elif key == "originalyear":
                return self.get("originaldate", default)[:4]
            elif key == "#originalyear":
                try:
                    return int(self.get("originaldate", default)[:4])
                except (ValueError, TypeError, KeyError):
                    return default
            elif key == "#tracks":
                try:
                    return int(self["tracknumber"].split("/")[1])
                except (ValueError, IndexError, TypeError, KeyError):
                    return default
            elif key == "#discs":
                try:
                    return int(self["discnumber"].split("/")[1])
                except (ValueError, IndexError, TypeError, KeyError):
                    return default
            elif key == "lyrics":
                # First, try the embedded lyrics.
                try:
                    return self["lyrics"]
                except KeyError:
                    pass

                try:
                    return self["unsyncedlyrics"]
                except KeyError:
                    pass

                # If there are no embedded lyrics, try to read them from
                # the external file.
                lyric_filename = self.lyric_filename
                if not lyric_filename:
                    return default
                try:
                    with open(lyric_filename, "rb") as fileobj:
                        print_d(f"Reading lyrics from {lyric_filename!r}")
                        text = fileobj.read().decode("utf-8", "replace")
                        # try to skip binary files
                        if "\0" in text:
                            return default
                        return text
                except (EnvironmentError, UnicodeDecodeError):
                    return default
            elif key == "filesize":
                return util.format_size(self("~#filesize", 0))
            elif key == "playlists":
                # TODO: avoid static dependency here... somehow
                from quodlibet import app
                lib = app.library
                if not lib:
                    return ""
                playlists = lib.playlists.playlists_featuring(self)
                return "\n".join(s.name for s in playlists) or default
            elif key.startswith("#replaygain_"):
                try:
                    val = self.get(key[1:], default)
                    return round(float(val.split(" ")[0]), 2)
                except (ValueError, TypeError, AttributeError):
                    return default
            elif key[:1] == "#":
                key = "~" + key
                if key in self:
                    return self[key]
                elif key in NUMERIC_ZERO_DEFAULT:
                    return 0
                else:
                    try:
                        val = self[key[2:]]
                    except KeyError:
                        return default
                    try:
                        return int(val)
                    except ValueError:
                        try:
                            return float(val)
                        except ValueError:
                            return default
            else:
                return dict.get(self, "~" + key, default)

        elif key == "title":
            title = dict.get(self, "title")
            if title is None:
                # build a title with missing_title_template option
                unknown_track_template = _(
                    config.gettext("browsers", "missing_title_template"))

                from quodlibet.pattern import Pattern
                try:
                    pattern = Pattern(unknown_track_template)
                except ValueError:
                    title = decode_value("~basename", self("~basename"))
                else:
                    title = pattern % self

            return title
        elif key in SORT_TO_TAG:
            try:
                return self[key]
            except KeyError:
                key = SORT_TO_TAG[key]
        return dict.get(self, key, default)
示例#19
0
 def activated(self, tag, value):
     spls = config.gettext("editing", "split_on").split()
     return [(tag, v) for v in split_value(value, spls)]
示例#20
0
 def format(song: AudioFile) -> List[Tuple[Text, Text]]:
     fmt = config.gettext("settings",
                          "datecolumn_timestamp_format")
     date_str = format_date(song(cat), fmt)
     return [(date_str, date_str)]
示例#21
0
 def restore(self):
     text = config.gettext("browsers", "query_text")
     self.__searchbar.set_text(text)
     self.__query_changed(None, text, restore=True)
示例#22
0
 def activated(self, tag, value):
     spls = config.gettext("editing", "split_on").split()
     return [(tag, v) for v in split_value(value, spls)]
示例#23
0
 def filter(self, tag, value):
     spls = config.gettext("editing", "split_on")
     spls = spls.split()
     return "\n".join(split_value(value, spls))
示例#24
0
 def filter(self, tag, value):
     spls = config.gettext("editing", "split_on")
     spls = spls.split()
     return "\n".join(split_value(value, spls))
示例#25
0
 def restore(self):
     text = config.gettext("browsers", "query_text")
     self._set_text(text)
示例#26
0
文件: main.py 项目: zsau/quodlibet
 def restore(self):
     text = config.gettext("browsers", "query_text")
     self.__searchbar.set_text(text)
     self.__query_changed(None, text, restore=True)
示例#27
0
 def on_reverted(*args):
     config.reset(section, option)
     entry.set_text(config.gettext(section, option))
示例#28
0
 def on_reverted(*args):
     config.reset(section, option)
     entry.set_text(config.gettext(section, option))
示例#29
0
 def restore(self):
     text = config.gettext("browsers", "query_text")
     self._set_text(text)
示例#30
0
 def activated(self, tag, value):
     tag_spls = config.gettext("editing", "split_on").split()
     sub_spls = config.gettext("editing", "sub_split_on").split()
     artist, others = split_people(value, tag_spls, sub_spls)
     return [(tag, artist)] + [(self.needs[0], o) for o in others]
示例#31
0
 def activated(self, tag, value):
     tag_spls = config.gettext("editing", "split_on").split()
     sub_spls = config.gettext("editing", "sub_split_on").split()
     title, versions = split_title(value, tag_spls, sub_spls)
     return [(tag, title)] + [("version", v) for v in versions]