Example #1
0
 def filter(self, orig_or_tag, value):
     fr = gdecode(self._from.get_text())
     to = gdecode(self._to.get_text())
     try:
         return re.sub(fr, to, value)
     except:
         return value
Example #2
0
 def filter(self, orig_or_tag, value):
     fr = gdecode(self._from.get_text())
     to = gdecode(self._to.get_text())
     try:
         return re.sub(fr, to, value)
     except:
         return value
Example #3
0
    def __message(self, bus, message, librarian):
        if message.type == Gst.MessageType.EOS:
            print_d("Stream EOS")
            if not self._in_gapless_transition:
                self._source.next_ended()
            self._end(False)
        elif message.type == Gst.MessageType.TAG:
            self.__tag(message.parse_tag(), librarian)
        elif message.type == Gst.MessageType.ERROR:
            gerror, debug_info = message.parse_error()
            message = u""
            if gerror:
                message = util.gdecode(gerror.message).rstrip(".")
            details = None
            if debug_info:
                # strip the first line, not user friendly
                debug_info = "\n".join(debug_info.splitlines()[1:])
                # can contain paths, so not sure if utf-8 in all cases
                details = util.gdecode(debug_info)
            self._error(PlayerError(message, details))
        elif message.type == Gst.MessageType.STATE_CHANGED:
            # pulsesink doesn't notify a volume change on startup
            # and the volume is only valid in > paused states.
            if message.src is self._ext_vol_element:
                self.notify("volume")
            if message.src is self._ext_mute_element:
                self.notify("mute")
        elif message.type == Gst.MessageType.STREAM_START:
            if self._in_gapless_transition:
                print_d("Stream changed")
                self._end(False)
        elif message.type == Gst.MessageType.ELEMENT:
            message_name = message.get_structure().get_name()

            if message_name == "missing-plugin":
                self.__handle_missing_plugin(message)
        elif message.type == Gst.MessageType.CLOCK_LOST:
            print_d("Clock lost")
            self.bin.set_state(Gst.State.PAUSED)
            self.bin.set_state(Gst.State.PLAYING)
        elif message.type == Gst.MessageType.LATENCY:
            print_d("Recalculate latency")
            self.bin.recalculate_latency()
        elif message.type == Gst.MessageType.REQUEST_STATE:
            state = message.parse_request_state()
            print_d("State requested: %s" % Gst.Element.state_get_name(state))
            self.bin.set_state(state)
        elif message.type == Gst.MessageType.DURATION_CHANGED:
            if self.song.fill_length:
                ok, p = self.bin.query_duration(Gst.Format.TIME)
                if ok:
                    p /= float(Gst.SECOND)
                    self.song["~#length"] = p
                    librarian.changed([self.song])
Example #4
0
    def __message(self, bus, message, librarian):
        if message.type == Gst.MessageType.EOS:
            print_d("Stream EOS")
            if not self._in_gapless_transition:
                self._source.next_ended()
            self._end(False)
        elif message.type == Gst.MessageType.TAG:
            self.__tag(message.parse_tag(), librarian)
        elif message.type == Gst.MessageType.ERROR:
            gerror, debug_info = message.parse_error()
            message = u""
            if gerror:
                message = util.gdecode(gerror.message).rstrip(".")
            details = None
            if debug_info:
                # strip the first line, not user friendly
                debug_info = "\n".join(debug_info.splitlines()[1:])
                # can contain paths, so not sure if utf-8 in all cases
                details = util.gdecode(debug_info)
            self._error(PlayerError(message, details))
        elif message.type == Gst.MessageType.STATE_CHANGED:
            # pulsesink doesn't notify a volume change on startup
            # and the volume is only valid in > paused states.
            if message.src is self._ext_vol_element:
                self.notify("volume")
            if message.src is self._ext_mute_element:
                self.notify("mute")
        elif message.type == Gst.MessageType.STREAM_START:
            if self._in_gapless_transition:
                print_d("Stream changed")
                self._end(False)
        elif message.type == Gst.MessageType.ELEMENT:
            message_name = message.get_structure().get_name()

            if message_name == "missing-plugin":
                self.__handle_missing_plugin(message)
        elif message.type == Gst.MessageType.CLOCK_LOST:
            print_d("Clock lost")
            self.bin.set_state(Gst.State.PAUSED)
            self.bin.set_state(Gst.State.PLAYING)
        elif message.type == Gst.MessageType.LATENCY:
            print_d("Recalculate latency")
            self.bin.recalculate_latency()
        elif message.type == Gst.MessageType.REQUEST_STATE:
            state = message.parse_request_state()
            print_d("State requested: %s" % Gst.Element.state_get_name(state))
            self.bin.set_state(state)
        elif message.type == Gst.MessageType.DURATION_CHANGED:
            if self.song.fill_length:
                ok, p = self.bin.query_duration(Gst.Format.TIME)
                if ok:
                    p /= float(Gst.SECOND)
                    self.song["~#length"] = p
                    librarian.changed([self.song])
Example #5
0
    def __match_filter(self, completion, entrytext, iter, data):
        model = completion.get_model()
        entry = self.get_entry()
        entrytext = gdecode(entrytext)
        if entry is None:
            return False
        cursor = entry.get_position()
        if (cursor != len(entrytext) and not max(
            [entrytext[cursor:].startswith(s) for s in self.rightsep])):
            return False

        # find the border to the left
        left, f = max([(entrytext.rfind(c, 0, cursor), c)
                       for c in self.leftsep])
        if left < 0:
            left += 1
        else:
            left += len(f)

        if left == cursor:
            return False
        key = entrytext[left:cursor]

        value = model.get_value(iter, self.get_property('text-column'))
        return bool(value and value.startswith(key))
Example #6
0
def GStreamerSink(pipeline_desc):
    """Returns a list of unlinked gstreamer elements ending with an audio sink
    and a textual description of the pipeline.

    `pipeline_desc` can be gst-launch syntax for multiple elements
    with or without an audiosink.

    In case of an error, raises PlayerError
    """

    pipe = None
    if pipeline_desc:
        try:
            pipe = [Gst.parse_launch(e) for e in pipeline_desc.split('!')]
        except GLib.GError as e:
            message = gdecode(e.message)
            raise PlayerError(_("Invalid GStreamer output pipeline"), message)

    if pipe:
        # In case the last element is linkable with a fakesink
        # it is not an audiosink, so we append the default one
        fake = Gst.ElementFactory.make('fakesink', None)
        if link_many([pipe[-1], fake]):
            unlink_many([pipe[-1], fake])
            default_elm, default_desc = find_audio_sink()
            pipe += [default_elm]
            pipeline_desc += " ! " + default_desc
    else:
        elm, pipeline_desc = find_audio_sink()
        pipe = [elm]

    return pipe, pipeline_desc
Example #7
0
    def __edit_tag(self, renderer, path, new_value, model):
        new_value = gdecode(new_value)
        new_value = ', '.join(new_value.splitlines())
        path = Gtk.TreePath.new_from_string(path)
        entry = model[path][0]
        error_dialog = None

        if not massagers.is_valid(entry.tag, new_value):
            error_dialog = qltk.WarningMessage(
                self, _("Invalid value"),
                _("Invalid value: <b>%(value)s</b>\n\n%(error)s") % {
                "value": new_value,
                "error": massagers.error_message(entry.tag, new_value)})
        else:
            new_value = massagers.validate(entry.tag, new_value)

        comment = entry.value
        changed = comment.text != new_value
        if (changed and ((comment.shared and comment.complete) or new_value)) \
                or (new_value and comment.shared and not comment.complete):
            # only give an error if we would have applied the value
            if error_dialog is not None:
                error_dialog.run()
                return
            entry.value = Comment(new_value)
            entry.edited = True
            entry.deleted = False
            model.path_changed(path)
Example #8
0
 def __row_edited(self, renderer, path, new, model, header):
     entry = model[path][0]
     new = gdecode(new)
     if entry.get_match(header) != new:
         entry.replace_match(header, new)
         self.preview.set_sensitive(True)
         self.save.set_sensitive(True)
Example #9
0
    def __match_filter(self, completion, entrytext, iter, data):
        model = completion.get_model()
        entry = self.get_entry()
        entrytext = gdecode(entrytext)
        if entry is None:
            return False
        cursor = entry.get_position()
        if (cursor != len(entrytext) and not
            max([entrytext[cursor:].startswith(s) for s in self.rightsep])):
            return False

        # find the border to the left
        left, f = max(
            [(entrytext.rfind(c, 0, cursor), c) for c in self.leftsep])
        if left < 0:
            left += 1
        else:
            left += len(f)

        if left == cursor:
            return False
        key = entrytext[left:cursor]

        value = model.get_value(iter, self.get_property('text-column'))
        return bool(value and value.startswith(key))
Example #10
0
    def __filter(self, model, iter_, data):
        """Filter a single row"""
        plugin = model.get_value(iter_)
        if not plugin:
            return False

        entry, state_combo, type_combo = data

        plugin_type = type_combo.get_active_type()
        if not issubclass(plugin.cls, plugin_type):
            return False

        tag_row = state_combo.get_active_row()
        if tag_row:
            plugin_tags = plugin.tags
            tag, flag = tag_row
            enabled = plugin_enabled(plugin)
            if (flag == EnabledType.NO and plugin_tags
                    or flag == EnabledType.TAG and tag not in plugin_tags
                    or flag == EnabledType.EN and not enabled
                    or flag == EnabledType.DIS and enabled):
                return False

        filter_ = util.gdecode(entry.get_text()).lower()
        return (not filter_ or filter_ in plugin.name.lower()
                or filter_ in (plugin.description or "").lower())
Example #11
0
    def __edit_tag(self, renderer, path, new_value, model):
        new_value = gdecode(new_value)
        new_value = ', '.join(new_value.splitlines())
        path = Gtk.TreePath.new_from_string(path)
        entry = model[path][0]
        error_dialog = None

        if not massagers.is_valid(entry.tag, new_value):
            error_dialog = qltk.WarningMessage(
                self, _("Invalid value"),
                _("Invalid value: <b>%(value)s</b>\n\n%(error)s") % {
                    "value": new_value,
                    "error": massagers.error_message(entry.tag, new_value)
                })
        else:
            new_value = massagers.validate(entry.tag, new_value)

        comment = entry.value
        changed = comment.text != new_value
        if (changed and ((comment.shared and comment.complete) or new_value)) \
                or (new_value and comment.shared and not comment.complete):
            # only give an error if we would have applied the value
            if error_dialog is not None:
                error_dialog.run()
                return
            entry.value = Comment(new_value)
            entry.edited = True
            entry.deleted = False
            model.path_changed(path)
Example #12
0
 def __row_edited(self, renderer, path, new, model, header):
     entry = model[path][0]
     new = gdecode(new)
     if entry.get_match(header) != new:
         entry.replace_match(header, new)
         self.preview.set_sensitive(True)
         self.save.set_sensitive(True)
Example #13
0
    def get_comment(self):
        """Returns the user provided error description

        Returns
            text_Type
        """

        return util.gdecode(self._entry.get_text())
Example #14
0
    def get_comment(self):
        """Returns the user provided error description

        Returns
            text_Type
        """

        return util.gdecode(self._entry.get_text())
Example #15
0
 def __row_edited(self, renderer, path, new):
     path = Gtk.TreePath.new_from_string(path)
     model = self.view.get_model()
     entry = model[path][0]
     new = gdecode(new)
     if entry.new_name != new:
         entry.new_name = new
         self.preview.set_sensitive(True)
         self.save.set_sensitive(True)
         model.path_changed(path)
Example #16
0
 def __row_edited(self, renderer, path, new):
     path = Gtk.TreePath.new_from_string(path)
     model = self.view.get_model()
     entry = model[path][0]
     new = gdecode(new)
     if entry.new_name != new:
         entry.new_name = new
         self.preview.set_sensitive(True)
         self.save.set_sensitive(True)
         model.path_changed(path)
Example #17
0
 def __row_edited(self, render, path, new, model, preview, save):
     path = Gtk.TreePath.new_from_string(path)
     row = model[path]
     entry = row[0]
     new = gdecode(new)
     if entry.tracknumber != new:
         entry.tracknumber = new
         preview.set_sensitive(True)
         save.set_sensitive(True)
         model.path_changed(path)
Example #18
0
    def do_get_preferred_width(self):
        widths = Gtk.Label.do_get_preferred_width(self)

        # If for same number of characters, the needed width was larger,
        # use that instead of the current one
        num_chars = len(gdecode(self.get_text()))
        max_widths = self.__widths.get(num_chars, widths)
        widths = max(widths[0], max_widths[0]), max(widths[1], max_widths[1])
        self.__widths[num_chars] = widths
        return widths
Example #19
0
    def do_get_preferred_width(self):
        widths = Gtk.Label.do_get_preferred_width(self)

        # If for same number of characters, the needed width was larger,
        # use that instead of the current one
        num_chars = len(gdecode(self.get_text()))
        max_widths = self.__widths.get(num_chars, widths)
        widths = max(widths[0], max_widths[0]), max(widths[1], max_widths[1])
        self.__widths[num_chars] = widths
        return widths
Example #20
0
 def __row_edited(self, render, path, new, model, preview, save):
     path = Gtk.TreePath.new_from_string(path)
     row = model[path]
     entry = row[0]
     new = gdecode(new)
     if entry.tracknumber != new:
         entry.tracknumber = new
         preview.set_sensitive(True)
         save.set_sensitive(True)
         model.path_changed(path)
Example #21
0
    def __changed_entry(self, entry, label, frame):
        text = gdecode(entry.get_text())

        if app.player.info is None:
            text = _("Not playing")
        else:
            text = Pattern(text) % app.player.info

        label.set_text(text)
        frame.set_tooltip_text(text)
        pconfig.set("tooltip", entry.get_text())
Example #22
0
    def __changed_entry(self, entry, label, frame):
        text = gdecode(entry.get_text())

        if app.player.info is None:
            text = _("Not playing")
        else:
            text = Pattern(text) % app.player.info

        label.set_text(text)
        frame.set_tooltip_text(text)
        pconfig.set("tooltip", entry.get_text())
Example #23
0
def get_backend_name():
    """The GDK backend name"""

    display = Gdk.Display.get_default()
    if display is not None:
        name = gdecode(display.__gtype__.name)
        if name.startswith("Gdk"):
            name = name[3:]
        if name.endswith("Display"):
            name = name[:-7]
        return name
    return u"Unknown"
Example #24
0
    def __save(self, addreplace, library):
        pattern_text = gdecode(self.combo.get_child().get_text())
        pattern = TagsFromPattern(pattern_text)
        model = self.view.get_model()
        add = bool(addreplace.get_active())
        win = WritingWindow(self, len(model))
        win.show()

        was_changed = set()

        all_done = False
        for entry in ((model and itervalues(model)) or []):
            song = entry.song
            changed = False
            if not song.valid():
                win.hide()
                dialog = OverwriteWarning(self, song)
                resp = dialog.run()
                win.show()
                if resp != OverwriteWarning.RESPONSE_SAVE:
                    break

            for i, h in enumerate(pattern.headers):
                text = entry.get_match(h)
                if text:
                    can_multiple = song.can_multiple_values(h)
                    if not add or h not in song or not can_multiple:
                        song[h] = text
                        changed = True
                    else:
                        for val in text.split("\n"):
                            if val not in song.list(h):
                                song.add(h, val)
                                changed = True

            if changed:
                try:
                    song.write()
                except AudioFileError:
                    util.print_exc()
                    WriteFailedError(self, song).run()
                    library.reload(song, changed=was_changed)
                    break
                was_changed.add(song)

            if win.step():
                break
        else:
            all_done = True

        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(not all_done)
Example #25
0
    def __save(self, addreplace, library):
        pattern_text = gdecode(self.combo.get_child().get_text())
        pattern = TagsFromPattern(pattern_text)
        model = self.view.get_model()
        add = bool(addreplace.get_active())
        win = WritingWindow(self, len(model))
        win.show()

        was_changed = set()

        all_done = False
        for entry in ((model and model.itervalues()) or []):
            song = entry.song
            changed = False
            if not song.valid():
                win.hide()
                dialog = OverwriteWarning(self, song)
                resp = dialog.run()
                win.show()
                if resp != OverwriteWarning.RESPONSE_SAVE:
                    break

            for i, h in enumerate(pattern.headers):
                text = entry.get_match(h)
                if text:
                    can_multiple = song.can_multiple_values(h)
                    if not add or h not in song or not can_multiple:
                        song[h] = text
                        changed = True
                    else:
                        for val in text.split("\n"):
                            if val not in song.list(h):
                                song.add(h, val)
                                changed = True

            if changed:
                try:
                    song.write()
                except AudioFileError:
                    util.print_exc()
                    WriteFailedError(self, song).run()
                    library.reload(song, changed=was_changed)
                    break
                was_changed.add(song)

            if win.step():
                break
        else:
            all_done = True

        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(not all_done)
Example #26
0
def get_backend_name():
    """The GDK backend name"""

    display = Gdk.Display.get_default()
    if display is not None:
        name = gdecode(display.__gtype__.name)
        if name.startswith("Gdk"):
            name = name[3:]
        if name.endswith("Display"):
            name = name[:-7]
        return name
    return u"Unknown"
Example #27
0
    def _do_query(self, *args):
        """Search for album using the query text."""

        query = util.gdecode(self.search_query.get_text())

        if not query:
            self.result_label.set_markup("<b>%s</b>" % _("Please enter a query."))
            self.search_button.set_sensitive(True)
            return

        self.result_label.set_markup("<i>%s</i>" % _(u"Searching…"))

        self._qthread.add(self._process_results, search_releases, query)
Example #28
0
 def __search_func(self, model, column, key, iter_, data):
     album = model.get_album(iter_)
     if album is None:
         return config.getboolean("browsers", "covergrid_all", False)
     key = util.gdecode(key).lower()
     title = album.title.lower()
     if key in title:
         return False
     if config.getboolean("browsers", "album_substrings"):
         people = (p.lower() for p in album.list("~people"))
         for person in people:
             if key in person:
                 return False
     return True
Example #29
0
    def _do_query(self, *args):
        """Search for album using the query text."""

        query = util.gdecode(self.search_query.get_text())

        if not query:
            self.result_label.set_markup("<b>%s</b>" %
                                         _("Please enter a query."))
            self.search_button.set_sensitive(True)
            return

        self.result_label.set_markup("<i>%s</i>" % _(u"Searching…"))

        self._qthread.add(self._process_results, search_releases, query)
Example #30
0
    def __handle_missing_plugin(self, message):
        get_installer_detail = \
            GstPbutils.missing_plugin_message_get_installer_detail
        get_description = GstPbutils.missing_plugin_message_get_description

        details = get_installer_detail(message)
        if details is None:
            return

        self.stop()

        format_desc = get_description(message)
        title = _(u"No GStreamer element found to handle media format")
        error_details = _(u"Media format: %(format-description)s") % {
            "format-description": util.gdecode(format_desc)
        }

        def install_done_cb(plugins_return, *args):
            print_d("Gstreamer plugin install return: %r" % plugins_return)
            Gst.update_registry()

        context = GstPbutils.InstallPluginsContext.new()

        # new in 1.6
        if hasattr(context, "set_desktop_id"):
            from gi.repository import Gtk
            context.set_desktop_id(app.id)

        # new in 1.6
        if hasattr(context, "set_startup_notification_id"):
            current_time = Gtk.get_current_event_time()
            context.set_startup_notification_id("_TIME%d" % current_time)

        gdk_window = app.window.get_window()
        if gdk_window:
            try:
                xid = gdk_window.get_xid()
            except AttributeError:  # non X11
                pass
            else:
                context.set_xid(xid)

        res = GstPbutils.install_plugins_async([details], context,
                                               install_done_cb, None)
        print_d("Gstreamer plugin install result: %r" % res)

        if res in (GstPbutils.InstallPluginsReturn.HELPER_MISSING,
                   GstPbutils.InstallPluginsReturn.INTERNAL_FAILURE):
            self._error(PlayerError(title, error_details))
Example #31
0
    def __handle_missing_plugin(self, message):
        get_installer_detail = \
            GstPbutils.missing_plugin_message_get_installer_detail
        get_description = GstPbutils.missing_plugin_message_get_description

        details = get_installer_detail(message)
        if details is None:
            return

        self.stop()

        format_desc = get_description(message)
        title = _(u"No GStreamer element found to handle media format")
        error_details = _(u"Media format: %(format-description)s") % {
            "format-description": util.gdecode(format_desc)}

        def install_done_cb(plugins_return, *args):
            print_d("Gstreamer plugin install return: %r" % plugins_return)
            Gst.update_registry()

        context = GstPbutils.InstallPluginsContext.new()

        # new in 1.6
        if hasattr(context, "set_desktop_id"):
            from gi.repository import Gtk
            context.set_desktop_id(app.id)

        # new in 1.6
        if hasattr(context, "set_startup_notification_id"):
            current_time = Gtk.get_current_event_time()
            context.set_startup_notification_id("_TIME%d" % current_time)

        gdk_window = app.window.get_window()
        if gdk_window:
            try:
                xid = gdk_window.get_xid()
            except AttributeError:  # non X11
                pass
            else:
                context.set_xid(xid)

        res = GstPbutils.install_plugins_async(
            [details], context, install_done_cb, None)
        print_d("Gstreamer plugin install result: %r" % res)

        if res in (GstPbutils.InstallPluginsReturn.HELPER_MISSING,
                GstPbutils.InstallPluginsReturn.INTERNAL_FAILURE):
            self._error(PlayerError(title, error_details))
Example #32
0
    def __color(self, widget, validator):
        value = validator(gdecode(self.get_text()))
        if value is True:
            color = self.VALID
        elif value is False:
            color = self.INVALID
        elif value and isinstance(value, basestring):
            color = Gdk.RGBA()
            color.parse(value)
        else:
            color = None

        if color and self.get_property('sensitive'):
            self.override_color(Gtk.StateType.NORMAL, color)
        else:
            self.override_color(Gtk.StateType.NORMAL, None)
Example #33
0
    def __color(self, widget, validator):
        value = validator(gdecode(self.get_text()))
        if value is True:
            color = self.VALID
        elif value is False:
            color = self.INVALID
        elif value and isinstance(value, basestring):
            color = Gdk.RGBA()
            color.parse(value)
        else:
            color = None

        if color and self.get_property('sensitive'):
            self.override_color(Gtk.StateType.NORMAL, color)
        else:
            self.override_color(Gtk.StateType.NORMAL, None)
Example #34
0
    def __match_selected(self, completion, model, iter):
        value = model.get_value(iter, self.get_property('text-column'))
        entry = self.get_entry()
        cursor = entry.get_position()

        text = entry.get_text()
        text = gdecode(text)
        left, f = max([(text.rfind(c, 0, cursor), c) for c in self.leftsep])
        if left == -1:
            left += 1
        else:
            left += len(f)
        offset = cursor - left

        entry.insert_text(value[offset:], cursor)
        entry.set_position(left + len(value))
        return True
Example #35
0
    def __match_selected(self, completion, model, iter):
        value = model.get_value(iter, self.get_property("text-column"))
        entry = self.get_entry()
        cursor = entry.get_position()

        text = entry.get_text()
        text = gdecode(text)
        left, f = max([(text.rfind(c, 0, cursor), c) for c in self.leftsep])
        if left == -1:
            left += 1
        else:
            left += len(f)
        offset = cursor - left

        entry.insert_text(value[offset:], cursor)
        entry.set_position(left + len(value))
        return True
Example #36
0
    def __preview(self, songs):
        model = self.view.get_model()
        if songs is None:
            songs = [e.song for e in model.itervalues()]

        pattern_text = gdecode(self.combo.get_child().get_text())

        try:
            pattern = FileFromPattern(pattern_text)
        except ValueError:
            qltk.ErrorMessage(
                self, _("Path is not absolute"),
                _("The pattern\n\t<b>%s</b>\ncontains / but "
                  "does not start from root. To avoid misnamed "
                  "folders, root your pattern by starting "
                  "it with / or ~/.") % (
                util.escape(pattern))).run()
            return
        else:
            if pattern:
                self.combo.prepend_text(pattern_text)
                self.combo.write(NBP)

        # native paths
        orignames = [song["~filename"] for song in songs]
        newnames = [pattern.format(song) for song in songs]
        for f in self.filter_box.filters:
            if f.active:
                newnames = f.filter_list(orignames, newnames)

        model.clear()
        for song, newname in zip(songs, newnames):
            entry = Entry(song)
            entry.new_name = fsdecode(newname)
            model.append(row=[entry])

        self.preview.set_sensitive(False)
        self.save.set_sensitive(bool(pattern_text))
        for song in songs:
            if not song.is_file:
                self.set_sensitive(False)
                break
        else:
            self.set_sensitive(True)
Example #37
0
    def _preview(self, songs):
        model = self.view.get_model()
        if songs is None:
            songs = [e.song for e in itervalues(model)]

        pattern_text = gdecode(self.combo.get_child().get_text())

        try:
            pattern = FileFromPattern(pattern_text)
        except ValueError:
            qltk.ErrorMessage(
                self, _("Path is not absolute"),
                _("The pattern\n\t<b>%s</b>\ncontains / but "
                  "does not start from root. To avoid misnamed "
                  "folders, root your pattern by starting "
                  "it with / or ~/.") % (util.escape(pattern_text))).run()
            return
        else:
            if pattern:
                self.combo.prepend_text(pattern_text)
                self.combo.write(NBP)

        # native paths
        orignames = [song["~filename"] for song in songs]
        newnames = [fsn2text(pattern.format(song)) for song in songs]
        for f in self.filter_box.filters:
            if f.active:
                newnames = f.filter_list(orignames, newnames)

        model.clear()
        for song, newname in zip(songs, newnames):
            entry = Entry(song)
            entry.new_name = newname
            model.append(row=[entry])

        self.preview.set_sensitive(False)
        self.save.set_sensitive(bool(pattern_text))
        for song in songs:
            if not song.is_file:
                self.set_sensitive(False)
                break
        else:
            self.set_sensitive(True)
Example #38
0
 def test_main(self):
     if PY2:
         self.assertTrue(isinstance(util.gdecode(b"foo"), text_type))
     else:
         self.assertTrue(isinstance(util.gdecode(u"foo"), text_type))
Example #39
0
 def __save(self, save, song, buffer, delete):
     start, end = buffer.get_bounds()
     text = util.gdecode(buffer.get_text(start, end, True))
     self._save_lyrics(song, text)
     delete.set_sensitive(True)
     save.set_sensitive(False)
Example #40
0
 def __all(self):
     text = gdecode(self.get_chars(0, -1))
     pos = self.get_position()
     return [text, pos]
Example #41
0
 def on_changed(entry, *args):
     config.settext(section, option, gdecode(entry.get_text()))
Example #42
0
 def first_draw(*args):
     filename = unexpand(self.dump_path)
     offset = gdecode(label.get_text()).find(filename)
     label.select_region(offset, offset + len(filename))
     self.disconnect(self.__draw_id)
Example #43
0
    def get_text(self):
        """Get the active text as unicode"""

        return gdecode(self.__entry.get_text())
Example #44
0
 def first_draw(*args):
     filename = unexpand(self.dump_path)
     offset = gdecode(label.get_text()).find(filename)
     label.select_region(offset, offset + len(filename))
     self.disconnect(self.__draw_id)
Example #45
0
 def __search_func(self, model, column, key, iter_, data):
     entry = model.get_value(iter_)
     return not entry.contains_text(gdecode(key))
Example #46
0
 def __all(self):
     text = gdecode(self.get_chars(0, -1))
     pos = self.get_position()
     return [text, pos]
Example #47
0
 def __equal(self, value):
     entry_val = gdecode(self.entry.get_text())
     self.failUnlessEqual(value, entry_val)
Example #48
0
 def on_textbuffer_changed(text_buffer, cfgname):
     start, end = text_buffer.get_bounds()
     text = gdecode(text_buffer.get_text(start, end, True))
     pconfig.settext(cfgname, text)
Example #49
0
    def __preview(self, songs):
        if songs is None:
            songs = [row[0].song for row in (self.view.get_model() or [])]

        if songs:
            pattern_text = gdecode(self.combo.get_child().get_text())
        else:
            pattern_text = ""
        try:
            pattern = TagsFromPattern(pattern_text)
        except re.error:
            qltk.ErrorMessage(
                self, _("Invalid pattern"),
                _("The pattern\n\t<b>%s</b>\nis invalid. "
                  "Possibly it contains the same tag twice or "
                  "it has unbalanced brackets (&lt; / &gt;).") %
                (util.escape(pattern_text))).run()
            return
        else:
            if pattern_text:
                self.combo.prepend_text(pattern_text)
                self.combo.write(TBP)

        invalid = []

        for header in pattern.headers:
            if not min([song.can_change(header) for song in songs]):
                invalid.append(header)
        if len(invalid) and songs:
            if len(invalid) == 1:
                title = _("Invalid tag")
                msg = _("Invalid tag <b>%s</b>\n\nThe files currently"
                        " selected do not support editing this tag.")
            else:
                title = _("Invalid tags")
                msg = _("Invalid tags <b>%s</b>\n\nThe files currently"
                        " selected do not support editing these tags.")
            qltk.ErrorMessage(self, title, msg % ", ".join(invalid)).run()
            pattern = TagsFromPattern("")

        self.view.set_model(None)
        model = ObjectStore()
        for col in self.view.get_columns():
            self.view.remove_column(col)

        render = Gtk.CellRendererText()
        col = TreeViewColumn(title=_('File'))
        col.pack_start(render, True)
        col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)

        def cell_data_file(column, cell, model, iter_, data):
            entry = model.get_value(iter_)
            cell.set_property("text", entry.name)

        col.set_cell_data_func(render, cell_data_file)

        def cell_data_header(column, cell, model, iter_, header):
            entry = model.get_value(iter_)
            cell.set_property("text", entry.get_match(header))

        self.view.append_column(col)
        for i, header in enumerate(pattern.headers):
            render = Gtk.CellRendererText()
            render.set_property('editable', True)
            render.connect('edited', self.__row_edited, model, header)
            escaped_title = header.replace("_", "__")
            col = Gtk.TreeViewColumn(escaped_title, render)
            col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
            col.set_cell_data_func(render, cell_data_header, header)
            self.view.append_column(col)

        for song in songs:
            entry = ListEntry(song)
            match = pattern.match(song)
            for h in pattern.headers:
                text = match.get(h, '')
                for f in self.filter_box.filters:
                    if f.active:
                        text = f.filter(h, text)
                if not song.can_multiple_values(h):
                    text = u", ".join(text.split("\n"))
                entry.matches[h] = text
            model.append([entry])

        # save for last to potentially save time
        if songs:
            self.view.set_model(model)
        self.preview.set_sensitive(False)
        self.save.set_sensitive(len(pattern.headers) > 0)
Example #50
0
 def get_value(self):
     return gdecode(self.__val.get_text())
Example #51
0
 def text(self):
     start, end = self.buffer.get_bounds()
     return gdecode(self.buffer.get_text(start, end, True))
Example #52
0
 def __equal(self, value):
     entry_val = gdecode(self.entry.get_text())
     self.failUnlessEqual(value, entry_val)
Example #53
0
 def get_value(self):
     return gdecode(self.__val.get_text())
Example #54
0
 def text(self):
     start, end = self.buffer.get_bounds()
     return gdecode(self.buffer.get_text(start, end, True))
Example #55
0
 def test_main(self):
     if PY2:
         self.assertTrue(isinstance(util.gdecode(b"foo"), text_type))
     else:
         self.assertTrue(isinstance(util.gdecode(u"foo"), text_type))
Example #56
0
 def on_entry_changed(entry, cfgname):
     pconfig.settext(cfgname, gdecode(entry.get_text()))
Example #57
0
    def __preview(self, songs):
        if songs is None:
            songs = [row[0].song for row in (self.view.get_model() or [])]

        if songs:
            pattern_text = gdecode(self.combo.get_child().get_text())
        else:
            pattern_text = ""
        try:
            pattern = TagsFromPattern(pattern_text)
        except re.error:
            qltk.ErrorMessage(
                self, _("Invalid pattern"),
                _("The pattern\n\t<b>%s</b>\nis invalid. "
                  "Possibly it contains the same tag twice or "
                  "it has unbalanced brackets (&lt; / &gt;).") % (
                util.escape(pattern_text))).run()
            return
        else:
            if pattern_text:
                self.combo.prepend_text(pattern_text)
                self.combo.write(TBP)

        invalid = []

        for header in pattern.headers:
            if not min([song.can_change(header) for song in songs]):
                invalid.append(header)
        if len(invalid) and songs:
            if len(invalid) == 1:
                title = _("Invalid tag")
                msg = _("Invalid tag <b>%s</b>\n\nThe files currently"
                        " selected do not support editing this tag.")
            else:
                title = _("Invalid tags")
                msg = _("Invalid tags <b>%s</b>\n\nThe files currently"
                        " selected do not support editing these tags.")
            qltk.ErrorMessage(
                self, title, msg % ", ".join(invalid)).run()
            pattern = TagsFromPattern("")

        self.view.set_model(None)
        model = ObjectStore()
        for col in self.view.get_columns():
            self.view.remove_column(col)

        render = Gtk.CellRendererText()
        col = TreeViewColumn(title=_('File'))
        col.pack_start(render, True)
        col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)

        def cell_data_file(column, cell, model, iter_, data):
            entry = model.get_value(iter_)
            cell.set_property("text", entry.name)

        col.set_cell_data_func(render, cell_data_file)

        def cell_data_header(column, cell, model, iter_, header):
            entry = model.get_value(iter_)
            cell.set_property("text", entry.get_match(header))

        self.view.append_column(col)
        for i, header in enumerate(pattern.headers):
            render = Gtk.CellRendererText()
            render.set_property('editable', True)
            render.connect('edited', self.__row_edited, model, header)
            escaped_title = header.replace("_", "__")
            col = Gtk.TreeViewColumn(escaped_title, render)
            col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
            col.set_cell_data_func(render, cell_data_header, header)
            self.view.append_column(col)

        for song in songs:
            entry = ListEntry(song)
            match = pattern.match(song)
            for h in pattern.headers:
                text = match.get(h, '')
                for f in self.filter_box.filters:
                    if f.active:
                        text = f.filter(h, text)
                if not song.can_multiple_values(h):
                    text = u", ".join(text.split("\n"))
                entry.matches[h] = text
            model.append([entry])

        # save for last to potentially save time
        if songs:
            self.view.set_model(model)
        self.preview.set_sensitive(False)
        self.save.set_sensitive(len(pattern.headers) > 0)