From 1af35153d93f5f772c735a2596cda6dc4f647779 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Sat, 12 Jun 2021 17:05:49 +0100 Subject: [PATCH] Add strikethrough and superscript/subscript support --- gramps/gen/lib/styledtexttagtype.py | 8 +++ gramps/gui/widgets/styledtextbuffer.py | 14 +++++ gramps/gui/widgets/styledtexteditor.py | 71 +++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/gramps/gen/lib/styledtexttagtype.py b/gramps/gen/lib/styledtexttagtype.py index 54866f7d4..587768ba4 100644 --- a/gramps/gen/lib/styledtexttagtype.py +++ b/gramps/gen/lib/styledtexttagtype.py @@ -53,6 +53,8 @@ class StyledTextTagType(GrampsType): HIGHLIGHT = 6 SUPERSCRIPT = 7 LINK = 8 + STRIKETHROUGH = 9 + SUBSCRIPT = 10 _CUSTOM = NONE_TYPE _DEFAULT = NONE_TYPE @@ -67,6 +69,8 @@ class StyledTextTagType(GrampsType): (HIGHLIGHT, _("Highlight"), "highlight"), (SUPERSCRIPT, _("Superscript"), "superscript"), (LINK, _("Link"), "link"), + (STRIKETHROUGH, _("Strikethrough"), "strikethrough"), + (SUBSCRIPT, _("Subscript"), "subscript"), ] STYLE_TYPE = { @@ -79,6 +83,8 @@ class StyledTextTagType(GrampsType): FONTSIZE: int, SUPERSCRIPT: bool, LINK: str, + STRIKETHROUGH: bool, + SUBSCRIPT: bool, } STYLE_DEFAULT = { @@ -91,6 +97,8 @@ class StyledTextTagType(GrampsType): FONTSIZE: 10, SUPERSCRIPT: False, LINK: '', + STRIKETHROUGH: False, + SUBSCRIPT: False, } def __init__(self, value=None): diff --git a/gramps/gui/widgets/styledtextbuffer.py b/gramps/gui/widgets/styledtextbuffer.py index 59bd657e9..ca05136bc 100644 --- a/gramps/gui/widgets/styledtextbuffer.py +++ b/gramps/gui/widgets/styledtextbuffer.py @@ -47,6 +47,8 @@ from .undoablebuffer import UndoableBuffer WEIGHT_BOLD = Pango.Weight.BOLD STYLE_ITALIC = Pango.Style.ITALIC UNDERLINE_SINGLE = Pango.Underline.SINGLE +RISE_SUPERSUB = 5000 +SCALE_SMALL = 1 / 1.2 #------------------------------------------------------------------------- # @@ -68,7 +70,10 @@ ALLOWED_STYLES = ( StyledTextTagType.HIGHLIGHT, StyledTextTagType.FONTFACE, StyledTextTagType.FONTSIZE, + StyledTextTagType.SUPERSCRIPT, StyledTextTagType.LINK, + StyledTextTagType.STRIKETHROUGH, + StyledTextTagType.SUBSCRIPT, ) STYLE_TO_PROPERTY = { @@ -79,7 +84,10 @@ STYLE_TO_PROPERTY = { StyledTextTagType.HIGHLIGHT: 'background', StyledTextTagType.FONTFACE: 'family', StyledTextTagType.FONTSIZE: 'size-points', + StyledTextTagType.SUPERSCRIPT: 'rise', StyledTextTagType.LINK: 'link', + StyledTextTagType.STRIKETHROUGH: 'strikethrough', # permanent tag + StyledTextTagType.SUBSCRIPT: 'rise', } (MATCH_START, @@ -271,6 +279,12 @@ class StyledTextBuffer(UndoableBuffer): self.create_tag(str(StyledTextTagType.ITALIC), style=STYLE_ITALIC) self.create_tag(str(StyledTextTagType.UNDERLINE), underline=UNDERLINE_SINGLE) + self.create_tag(str(StyledTextTagType.STRIKETHROUGH), + strikethrough=True) + self.create_tag(str(StyledTextTagType.SUPERSCRIPT), + rise=RISE_SUPERSUB, scale=SCALE_SMALL) + self.create_tag(str(StyledTextTagType.SUBSCRIPT), + rise=-RISE_SUPERSUB, scale=SCALE_SMALL) # internal format state attributes ## 1. are used to format inserted characters (self.after_insert_text) diff --git a/gramps/gui/widgets/styledtexteditor.py b/gramps/gui/widgets/styledtexteditor.py index 5be0faa24..8c01bb101 100644 --- a/gramps/gui/widgets/styledtexteditor.py +++ b/gramps/gui/widgets/styledtexteditor.py @@ -113,6 +113,36 @@ FORMAT_TOOLBAR = ( False + + + format-text-strikethrough + ste.STRIKETHROUGH + Strikethrough + + + False + + + + + format-text-superscript + ste.SUPERSCRIPT + Superscript + + + False + + + + + format-text-subscript + ste.SUBSCRIPT + Subscript + + + False + + Font family @@ -534,12 +564,24 @@ class StyledTextEditor(Gtk.TextView): builder = Gtk.Builder() builder.set_translation_domain(glocale.get_localedomain()) builder.add_from_string(FORMAT_TOOLBAR) + + # fallback icons + icon_theme = Gtk.IconTheme().get_default() + icon_theme.connect('changed', self.__set_fallback_icons, builder) + self.__set_fallback_icons(icon_theme, builder) + # define the actions... _actions = [ ('ITALIC', self._on_toggle_action_activate, 'i', False), ('BOLD', self._on_toggle_action_activate, 'b', False), ('UNDERLINE', self._on_toggle_action_activate, 'u', False), + ('STRIKETHROUGH', self._on_toggle_action_activate, 's', + False), + ('SUPERSCRIPT', self._on_toggle_action_activate, 'p', + False), + ('SUBSCRIPT', self._on_toggle_action_activate, 'c', + False), ('FONTCOLOR', self._on_action_activate), ('HIGHLIGHT', self._on_action_activate), ('LINK', self._on_link_activate), @@ -593,6 +635,20 @@ class StyledTextEditor(Gtk.TextView): return toolbar, self.action_group + def __set_fallback_icons(self, icon_theme, builder): + """ + Set fallbacks for icons that are not available in the current theme. + """ + fallbacks = (("superscript", "format-text-superscript", "go-up"), + ("subscript", "format-text-subscript", "go-down")) + for obj_name, primary, fallback in fallbacks: + tool_button = builder.get_object(obj_name) + icon = tool_button.get_child().get_child() + name = primary + if not icon_theme.has_icon(primary): + name = fallback + icon.set_from_icon_name(name, Gtk.IconSize.LARGE_TOOLBAR) + def set_transient_parent(self, parent=None): self.transient_parent = parent @@ -641,7 +697,8 @@ class StyledTextEditor(Gtk.TextView): """ Toggle a style. - Toggle styles are e.g. 'bold', 'italic', 'underline'. + Toggle styles are e.g. 'bold', 'italic', 'underline', 'strikethrough', + 'superscript' and 'subscript'. """ action.set_state(value) if self._internal_style_change: @@ -649,6 +706,15 @@ class StyledTextEditor(Gtk.TextView): style = action.get_name() value = value.get_boolean() + + if value and style in ('SUPERSCRIPT', 'SUBSCRIPT'): + if style == 'SUPERSCRIPT': + toggle_off = 'SUBSCRIPT' + else: + toggle_off = 'SUPERSCRIPT' + action = self.uimanager.get_action(self.action_group, toggle_off) + action.change_state(Variant.new_boolean(False)) + _LOG.debug("applying style '%s' with value '%s'" % (style, str(value))) self.textbuffer.apply_style(getattr(StyledTextTagType, style), value) @@ -771,7 +837,8 @@ class StyledTextEditor(Gtk.TextView): if not self.uimanager: return # never initialized a toolbar, not editable types = [StyledTextTagType.ITALIC, StyledTextTagType.BOLD, - StyledTextTagType.UNDERLINE] + StyledTextTagType.UNDERLINE, StyledTextTagType.STRIKETHROUGH, + StyledTextTagType.SUPERSCRIPT, StyledTextTagType.SUBSCRIPT] self._internal_style_change = True for style, style_value in changed_styles.items(): if style in types: