Exemplo n.º 1
0
def fmt_time_period_abbr(t):
    """Get a localized abbreviated minutes+seconds string

    :param int t: A positive number of seconds
    :returns: short localized string
    :rtype: unicode

    The result looks like like "<minutes>m<seconds>s",
    or just "<seconds>s".

    """
    if t < 0:
        raise ValueError("Parameter t cannot be negative")
    days = int(t / (24 * 60 * 60))
    hours = int(t - days * 24 * 60 * 60) / (60 * 60)
    minutes = int(t - hours * 60 * 60) / 60
    seconds = int(t - minutes * 60)
    # TRANSLATORS: I'm assuming that time periods in places where
    # TRANSLATORS: abbreviations make sense don't need ngettext()
    if t > 24 * 60 * 60:
        template = C_("Time period abbreviations", u"{days}d{hours}h")
    elif t > 60 * 60:
        template = C_("Time period abbreviations", u"{hours}h{minutes}m")
    elif t > 60:
        template = C_("Time period abbreviation", u"{minutes}m{seconds}s")
    else:
        template = C_("Time period abbreviation", u"{seconds}s")
    return template.format(
        days = days,
        hours = hours,
        minutes = minutes,
        seconds = seconds,
    )
Exemplo n.º 2
0
def fmt_time_period_abbr(t):
    """Get a localized abbreviated minutes+seconds string

    :param int t: A positive number of seconds
    :returns: short localized string
    :rtype: unicode

    The result looks like like "<minutes>m<seconds>s",
    or just "<seconds>s".

    """
    if t < 0:
        raise ValueError("Parameter t cannot be negative")
    days = int(t // (24 * 60 * 60))
    hours = int(t - days * 24 * 60 * 60) // (60 * 60)
    minutes = int(t - hours * 60 * 60) // 60
    seconds = int(t - minutes * 60)
    if t > 24 * 60 * 60:
        # TRANSLATORS: Assumption for all "Time period abbreviations":
        # TRANSLATORS: they don't need ngettext (to support plural/singular)
        template = C_("Time period abbreviations", u"{days}d{hours}h")
    elif t > 60 * 60:
        template = C_("Time period abbreviations", u"{hours}h{minutes}m")
    elif t > 60:
        template = C_("Time period abbreviation", u"{minutes}m{seconds}s")
    else:
        template = C_("Time period abbreviation", u"{seconds}s")
    return template.format(
        days = days,
        hours = hours,
        minutes = minutes,
        seconds = seconds,
    )
Exemplo n.º 3
0
 def _query_tooltip_cb(self, da, x, y, keyboard_mode, tooltip):
     s = self._TOOLTIP_ICON_SIZE
     scaled_pixbuf = self._get_scaled_pixbuf(s)
     tooltip.set_icon(scaled_pixbuf)
     template_params = {"brush_name": escape(self._brush_name)}
     markup_template = C_(
         "current brush indicator: tooltip (no-description case)",
         u"<b>{brush_name}</b>",
     )
     if self._brush_desc:
         markup_template = C_(
             "current brush indicator: tooltip (description case)",
             u"<b>{brush_name}</b>\n{brush_desc}",
         )
         template_params["brush_desc"] = escape(self._brush_desc)
     markup = markup_template.format(**template_params)
     tooltip.set_markup(markup)
     # TODO: summarize changes?
     return True
Exemplo n.º 4
0
 def _query_tooltip_cb(self, da, x, y, keyboard_mode, tooltip):
     s = self._TOOLTIP_ICON_SIZE
     scaled_pixbuf = self._get_scaled_pixbuf(s)
     tooltip.set_icon(scaled_pixbuf)
     template_params = {"brush_name": lib.xml.escape(self._brush_name)}
     markup_template = C_(
         "current brush indicator: tooltip (no-description case)",
         u"<b>{brush_name}</b>",
     )
     if self._brush_desc:
         markup_template = C_(
             "current brush indicator: tooltip (description case)",
             u"<b>{brush_name}</b>\n{brush_desc}",
         )
         template_params["brush_desc"] = lib.xml.escape(self._brush_desc)
     markup = markup_template.format(**template_params)
     tooltip.set_markup(markup)
     # TODO: summarize changes?
     return True
Exemplo n.º 5
0
 def _query_tooltip_cb(self, da, x, y, keyboard_mode, tooltip):
     s = self._TOOLTIP_ICON_SIZE
     scaled_pixbuf = self._get_scaled_pixbuf(s)
     tooltip.set_icon(scaled_pixbuf)
     brush_name = self._brush_name
     if not brush_name:
         brush_name = self._DEFAULT_BRUSH_DISPLAY_NAME
         # Rare cases, see https://github.com/mypaint/mypaint/issues/402.
         # Probably just after init.
     template_params = {"brush_name": lib.xml.escape(brush_name)}
     markup_template = C_("current brush indicator: tooltip (no-description case)", u"<b>{brush_name}</b>")
     if self._brush_desc:
         markup_template = C_(
             "current brush indicator: tooltip (description case)", u"<b>{brush_name}</b>\n{brush_desc}"
         )
         template_params["brush_desc"] = lib.xml.escape(self._brush_desc)
     markup = markup_template.format(**template_params)
     tooltip.set_markup(markup)
     # TODO: summarize changes?
     return True
Exemplo n.º 6
0
 def _query_tooltip_cb(self, da, x, y, keyboard_mode, tooltip):
     s = self._TOOLTIP_ICON_SIZE
     scaled_pixbuf = self._get_scaled_pixbuf(s)
     tooltip.set_icon(scaled_pixbuf)
     brush_name = self._brush_name
     if not brush_name:
         brush_name = self._DEFAULT_BRUSH_DISPLAY_NAME
         # Rare cases, see https://github.com/mypaint/mypaint/issues/402.
         # Probably just after init.
     template_params = {"brush_name": lib.xml.escape(brush_name)}
     markup_template = C_(
         "current brush indicator: tooltip (no-description case)",
         u"<b>{brush_name}</b>",
     )
     if self._brush_desc:
         markup_template = C_(
             "current brush indicator: tooltip (description case)",
             u"<b>{brush_name}</b>\n{brush_desc}",
         )
         template_params["brush_desc"] = lib.xml.escape(self._brush_desc)
     markup = markup_template.format(**template_params)
     tooltip.set_markup(markup)
     # TODO: summarize changes?
     return True
Exemplo n.º 7
0
    def _save_doc_to_file(self, filename, doc, export=False, statusmsg=True,
                          **options):
        """Saves a document to one or more files

        :param filename: The base filename to save
        :param gui.document.Document doc: Controller for the document to save
        :param bool export: True if exporting
        :param **options: Pass-through options

        This method handles logging, statusbar messages,
        and alerting the user to when the save failed.

        See also: `lib.document.Document.save()`.
        """
        thumbnail_pixbuf = None
        prefs = self.app.preferences
        display_colorspace_setting = prefs["display.colorspace"]
        options['save_srgb_chunks'] = (display_colorspace_setting == "srgb")
        if statusmsg:
            statusbar = self.app.statusbar
            statusbar_cid = self._statusbar_context_id
            statusbar.remove_all(statusbar_cid)
            file_basename = os.path.basename(filename)
            if export:
                during_tmpl = C_(
                    "file handling: during export (statusbar)",
                    u"Exporting to “{file_basename}”…"
                )
            else:
                during_tmpl = C_(
                    "file handling: during save (statusbar)",
                    u"Saving “{file_basename}”…"
                )
            statusbar.push(statusbar_cid, during_tmpl.format(
                file_basename = file_basename,
            ))
        try:
            x, y, w, h = doc.model.get_bbox()
            if w == 0 and h == 0:
                w, h = tiledsurface.N, tiledsurface.N
                # TODO: Add support for other sizes
            thumbnail_pixbuf = doc.model.save(
                filename,
                feedback_cb=self.gtk_main_tick,
                **options
            )
            self.lastsavefailed = False
        except (FileHandlingError, AllocationError, MemoryError) as e:
            if statusmsg:
                statusbar.remove_all(statusbar_cid)
                if export:
                    failed_tmpl = C_(
                        "file handling: export failure (statusbar)",
                        u"Failed to export to “{file_basename}”.",
                    )
                else:
                    failed_tmpl = C_(
                        "file handling: save failure (statusbar)",
                        u"Failed to save “{file_basename}”.",
                    )
                self.app.show_transient_message(failed_tmpl.format(
                    file_basename = file_basename,
                ))
            self.lastsavefailed = True
            self.app.message_dialog(unicode(e), type=Gtk.MessageType.ERROR)
        else:
            if statusmsg:
                statusbar.remove_all(statusbar_cid)
            file_location = os.path.abspath(filename)
            multifile_info = ''
            if "multifile" in options:
                multifile_info = " (basis; used multiple .XXX.ext names)"
            if not export:
                logger.info('Saved to %r%s', file_location, multifile_info)
            else:
                logger.info('Exported to %r%s', file_location, multifile_info)
            if statusmsg:
                if export:
                    success_tmpl = C_(
                        "file handling: export success (statusbar)",
                        u"Exported to “{file_basename}” successfully.",
                    )
                else:
                    success_tmpl = C_(
                        "file handling: save success (statusbar)",
                        u"Saved “{file_basename}” successfully.",
                    )
                self.app.show_transient_message(success_tmpl.format(
                    file_basename = file_basename,
                ))
        return thumbnail_pixbuf
Exemplo n.º 8
0
    def _layer_description_markup(layer):
        """GMarkup text description of a layer, used in the list."""
        name_markup = None
        description = None

        if layer is None:
            name_markup = escape(lib.layer.PlaceholderLayer.DEFAULT_NAME)
            description = C_(
                "Layers: description: no layer (\"never happens\" condition!)",
                u"?layer",
            )
        elif layer.name is None:
            name_markup = escape(layer.DEFAULT_NAME)
        else:
            name_markup = escape(layer.name)

        if layer is not None:
            desc_parts = []
            if isinstance(layer, lib.layer.LayerStack):
                name_markup = "<i>{}</i>".format(name_markup)

            # Mode (if it's interesting)
            if layer.mode in lib.modes.MODE_STRINGS:
                if layer.mode != lib.modes.default_mode():
                    s, d = lib.modes.MODE_STRINGS[layer.mode]
                    desc_parts.append(s)
            else:
                desc_parts.append(
                    C_(
                        "Layers: description parts: unknown mode (fallback str!)",
                        u"?mode",
                    ))

            # Visibility and opacity (if interesting)
            if not layer.visible:
                desc_parts.append(
                    C_(
                        "Layers: description parts: layer hidden",
                        u"Hidden",
                    ))
            elif layer.opacity < 1.0:
                desc_parts.append(
                    C_("Layers: description parts: opacity percentage",
                       u"%d%% opaque" % (round(layer.opacity * 100), )))

            # Locked flag (locked is interesting)
            if layer.locked:
                desc_parts.append(
                    C_(
                        "Layers dockable: description parts: layer locked flag",
                        u"Locked",
                    ))

            # Description of the layer's type.
            # Currently always used, for visual rhythm reasons, but it goes
            # on the end since it's perhaps the least interesting info.
            if layer.TYPE_DESCRIPTION is not None:
                desc_parts.append(layer.TYPE_DESCRIPTION)
            else:
                desc_parts.append(
                    C_(
                        "Layers: description parts: unknown type (fallback str!)",
                        u"?type",
                    ))

            # Stitch it all together
            if desc_parts:
                description = C_(
                    "Layers dockable: description parts joiner text",
                    u", ",
                ).join(desc_parts)
            else:
                description = None

        if description is None:
            markup_template = C_(
                "Layers dockable: markup for a layer with no description",
                u"{layer_name}",
            )
        else:
            markup_template = C_(
                "Layers dockable: markup for a layer with a description",
                '<span size="smaller">{layer_name}\n'
                '<span size="smaller">{layer_description}</span>'
                '</span>')

        markup = markup_template.format(
            layer_name=name_markup,
            layer_description=escape(description),
        )
        return markup
Exemplo n.º 9
0
    def _save_doc_to_file(self,
                          filename,
                          doc,
                          export=False,
                          statusmsg=True,
                          **options):
        """Saves a document to one or more files

        :param filename: The base filename to save
        :param gui.document.Document doc: Controller for the document to save
        :param bool export: True if exporting
        :param **options: Pass-through options

        This method handles logging, statusbar messages,
        and alerting the user to when the save failed.

        See also: `lib.document.Document.save()`.
        """
        thumbnail_pixbuf = None
        prefs = self.app.preferences
        display_colorspace_setting = prefs["display.colorspace"]
        options['save_srgb_chunks'] = (display_colorspace_setting == "srgb")
        if statusmsg:
            statusbar = self.app.statusbar
            statusbar_cid = self._statusbar_context_id
            statusbar.remove_all(statusbar_cid)
            file_basename = os.path.basename(filename)
            if export:
                during_tmpl = C_("file handling: during export (statusbar)",
                                 u"Exporting to “{file_basename}”…")
            else:
                during_tmpl = C_("file handling: during save (statusbar)",
                                 u"Saving “{file_basename}”…")
            statusbar.push(statusbar_cid,
                           during_tmpl.format(file_basename=file_basename, ))
        try:
            x, y, w, h = doc.model.get_bbox()
            if w == 0 and h == 0:
                w, h = tiledsurface.N, tiledsurface.N
                # TODO: Add support for other sizes
            thumbnail_pixbuf = doc.model.save(filename,
                                              feedback_cb=self.gtk_main_tick,
                                              **options)
            self.lastsavefailed = False
        except (FileHandlingError, AllocationError, MemoryError) as e:
            if statusmsg:
                statusbar.remove_all(statusbar_cid)
                if export:
                    failed_tmpl = C_(
                        "file handling: export failure (statusbar)",
                        u"Failed to export to “{file_basename}”.",
                    )
                else:
                    failed_tmpl = C_(
                        "file handling: save failure (statusbar)",
                        u"Failed to save “{file_basename}”.",
                    )
                self.app.show_transient_message(
                    failed_tmpl.format(file_basename=file_basename, ))
            self.lastsavefailed = True
            self.app.message_dialog(unicode(e), type=gtk.MESSAGE_ERROR)
        else:
            if statusmsg:
                statusbar.remove_all(statusbar_cid)
            file_location = os.path.abspath(filename)
            multifile_info = ''
            if "multifile" in options:
                multifile_info = " (basis; used multiple .XXX.ext names)"
            if not export:
                logger.info('Saved to %r%s', file_location, multifile_info)
            else:
                logger.info('Exported to %r%s', file_location, multifile_info)
            if statusmsg:
                if export:
                    success_tmpl = C_(
                        "file handling: export success (statusbar)",
                        u"Exported to “{file_basename}” successfully.",
                    )
                else:
                    success_tmpl = C_(
                        "file handling: save success (statusbar)",
                        u"Saved “{file_basename}” successfully.",
                    )
                self.app.show_transient_message(
                    success_tmpl.format(file_basename=file_basename, ))
        return thumbnail_pixbuf
Exemplo n.º 10
0
    >>> x2 = u'xyz 2'
    >>> make_unique_name(u"xyz", {}, start=2, always_number=u"xyz") == x2
    True

    """
    name = unicode(name)
    match = UNIQUE_NAME_REGEX.match(name)
    if match:
        base = match.group("name")
        num = int(match.group("number"))
    else:
        base = name
        num = max(0, int(start))
    force_numbering = (name == always_number)
    while (name in existing) or force_numbering:
        name = UNIQUE_NAME_TEMPLATE.format(name=base, number=num)
        num += 1
        force_numbering = False
    return name


assert UNIQUE_NAME_REGEX.match(
    UNIQUE_NAME_TEMPLATE.format(
        name="testing",
        number=12,
    )
), (
    "Translation error: lib.naming.UNIQUE_NAME_REGEX "
    "must match UNIQUE_NAME_TEMPLATE."
)
Exemplo n.º 11
0
    def _layer_description_markup(layer):
        """GMarkup text description of a layer, used in the list."""
        name_markup = None
        description = None

        if layer is None:
            name_markup = escape(lib.layer.PlaceholderLayer.DEFAULT_NAME)
            description = C_(
                "Layers: description: no layer (\"never happens\" condition!)",
                u"?layer",
            )
        elif layer.name is None:
            name_markup = escape(layer.DEFAULT_NAME)
        else:
            name_markup = escape(layer.name)

        if layer is not None:
            desc_parts = []
            if isinstance(layer, lib.layer.LayerStack):
                name_markup = "<i>{}</i>".format(name_markup)

            # Mode (if it's interesting)
            if layer.mode in lib.modes.MODE_STRINGS:
                if layer.mode != lib.modes.DEFAULT_MODE:
                    s, d = lib.modes.MODE_STRINGS[layer.mode]
                    desc_parts.append(s)
            else:
                desc_parts.append(C_(
                    "Layers: description parts: unknown mode (fallback str!)",
                    u"?mode",
                ))

            # Visibility and opacity (if interesting)
            if not layer.visible:
                desc_parts.append(C_(
                    "Layers: description parts: layer hidden",
                    u"Hidden",
                ))
            elif layer.opacity < 1.0:
                desc_parts.append(C_(
                    "Layers: description parts: opacity percentage",
                    u"%d%% opaque" % (round(layer.opacity * 100),)
                ))

            # Locked flag (locked is interesting)
            if layer.locked:
                desc_parts.append(C_(
                    "Layers dockable: description parts: layer locked flag",
                    u"Locked",
                ))

            # Description of the layer's type.
            # Currently always used, for visual rhythm reasons, but it goes
            # on the end since it's perhaps the least interesting info.
            if layer.TYPE_DESCRIPTION is not None:
                desc_parts.append(layer.TYPE_DESCRIPTION)
            else:
                desc_parts.append(C_(
                    "Layers: description parts: unknown type (fallback str!)",
                    u"?type",
                ))

            # Stitch it all together
            if desc_parts:
                description = C_(
                    "Layers dockable: description parts joiner text",
                    u", ",
                ).join(desc_parts)
            else:
                description = None

        if description is None:
            markup_template = C_(
                "Layers dockable: markup for a layer with no description",
                u"{layer_name}",
            )
        else:
            markup_template = C_(
                "Layers dockable: markup for a layer with a description",
                '<span size="smaller">{layer_name}\n'
                '<span size="smaller" alpha="50%">{layer_description}</span>'
                '</span>'
            )

        markup = markup_template.format(
            layer_name=name_markup,
            layer_description=escape(description),
        )
        return markup
Exemplo n.º 12
0
    item to be, for example, "Widget 1", not "Widget".

    >>> make_unique_name(u"xyz", {}, start=1, always_number=u"xyz")
    u'xyz 1'
    >>> make_unique_name(u"xyz", {}, start=2, always_number=u"xyz")
    u'xyz 2'

    """
    name = unicode(name)
    match = UNIQUE_NAME_REGEX.match(name)
    if match:
        base = match.group("name")
        num = int(match.group("number"))
    else:
        base = name
        num = max(0, int(start))
    force_numbering = (name == always_number)
    while (name in existing) or force_numbering:
        name = UNIQUE_NAME_TEMPLATE.format(name=base, number=num)
        num += 1
        force_numbering = False
    return name


assert UNIQUE_NAME_REGEX.match(
    UNIQUE_NAME_TEMPLATE.format(
        name="testing",
        number=12,
    )), ("Translation error: lib.naming.UNIQUE_NAME_REGEX "
         "must match UNIQUE_NAME_TEMPLATE.")
Exemplo n.º 13
0
    >>> x2 = u'xyz 2'
    >>> make_unique_name(u"xyz", {}, start=2, always_number=u"xyz") == x2
    True

    """
    name = unicode(name)
    match = UNIQUE_NAME_REGEX.match(name)
    if match:
        base = match.group("name")
        num = int(match.group("number"))
    else:
        base = name
        num = max(0, int(start))
    force_numbering = (name == always_number)
    while (name in existing) or force_numbering:
        name = UNIQUE_NAME_TEMPLATE.format(name=base, number=num)
        num += 1
        force_numbering = False
    return name


assert UNIQUE_NAME_REGEX.match(
    UNIQUE_NAME_TEMPLATE.format(
        name="testing",
        number=12,
    )
), (
    "Translation error: lib.naming.UNIQUE_NAME_REGEX "
    "must match UNIQUE_NAME_TEMPLATE."
)