diff --git a/gajim/data/style/gajim.css b/gajim/data/style/gajim.css index c9f982e748e7a70d5f1818dfb249521186f2493a..33b93131937ad64ffc37f42cde0bb5f9f14b5e6f 100644 --- a/gajim/data/style/gajim.css +++ b/gajim/data/style/gajim.css @@ -88,6 +88,20 @@ .conversation-nickname { font-size: small; font-weight: bold; } +.code-widget { + border: 1px solid @borders; + border-radius: 4px; +} +.code-widget-header { + background-color: alpha(@insensitive_fg_color, 0.4); + padding: 0 6px; +} +.code-widget-header label { + font-size: small; +} +.code-widget-header button { + padding: 0; +} .link-button { min-height: 0px; } diff --git a/gajim/gtk/conversation/code_widget.py b/gajim/gtk/conversation/code_widget.py index 8601bce027c1a4b96ca93a2d8bc2cb2526b8711b..d347543fefac5be4306af5df45ef0005b67772cd 100644 --- a/gajim/gtk/conversation/code_widget.py +++ b/gajim/gtk/conversation/code_widget.py @@ -12,34 +12,77 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see <http://www.gnu.org/licenses/>. +import logging + import gi gi.require_version('GtkSource', '4') from gi.repository import GObject +from gi.repository import Gdk from gi.repository import Gtk from gi.repository import GtkSource +from gajim.common.i18n import _ + +log = logging.getLogger('gajim.gui.conversation.code_widget') + class CodeWidget(Gtk.Box): def __init__(self, account): Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL) self.set_vexpand(True) + self.get_style_context().add_class('code-widget') self._account = account + header = Gtk.Box() + header.set_spacing(6) + header.get_style_context().add_class('code-widget-header') + self._lang_label = Gtk.Label() + header.add(self._lang_label) + + copy_button = Gtk.Button.new_from_icon_name( + 'edit-copy-symbolic', Gtk.IconSize.MENU) + copy_button.set_tooltip_text(_('Copy code snippet')) + copy_button.connect('clicked', self._on_copy) + header.add(copy_button) + self.add(header) + self._textview = CodeTextview() - # self._scrolled = Gtk.ScrolledWindow() - # self._scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, - # Gtk.PolicyType.AUTOMATIC) - # self._scrolled.set_hexpand(True) - # self._scrolled.set_vexpand(True) - # self._scrolled.set_propagate_natural_height(True) - # self._scrolled.set_max_content_height(400) - # self._scrolled.add(self._textview) + self._scrolled = Gtk.ScrolledWindow() + self._scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, + Gtk.PolicyType.AUTOMATIC) + self._scrolled.set_hexpand(True) + self._scrolled.set_vexpand(True) + self._scrolled.set_propagate_natural_height(True) + self._scrolled.set_max_content_height(400) + self._scrolled.add(self._textview) + + self.add(self._scrolled) - self.add(self._textview) + def _on_copy(self, _button): + text = self._textview.get_code() + clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + clipboard.set_text(text, -1) def add_content(self, block): - self._textview.print_code(block) + code, lang = self._prepare_code(block.text) + lang_name = self._textview.set_language(lang) + if lang is None: + self._lang_label.set_text(_('Code snippet')) + else: + self._lang_label.set_text(_('Code snippet (%s)') % lang_name) + + self._textview.print_code(code) + + @staticmethod + def _prepare_code(text): + code_start = text.partition('\n')[0] + lang = None + if len(code_start) > 3: + lang = code_start[3:] + + code = text.partition('\n')[2][:-4] + return code, lang class CodeTextview(GtkSource.View): @@ -51,9 +94,21 @@ def __init__(self): self._source_manager = GtkSource.LanguageManager.get_default() - def print_code(self, block): + def set_language(self, language_string): + if language_string is None: + lang = self._source_manager.get_language('python3') + else: + lang = self._source_manager.get_language(language_string) + log.debug('Code snippet lang: %s', lang.get_name()) + self.get_buffer().set_language(lang) + return lang.get_name() + + def get_code(self): buffer_ = self.get_buffer() - lang = self._source_manager.get_language('python3') - buffer_.set_language(lang) + start, end = buffer_.get_bounds() + return buffer_.get_text(start, end, False) + + def print_code(self, code): self.set_show_line_numbers(True) - buffer_.insert(buffer_.get_start_iter(), block.text) + buffer_ = self.get_buffer() + buffer_.insert(buffer_.get_start_iter(), code)