Commit 02dcbd6d authored by Kai Willadsen's avatar Kai Willadsen

sourceview: Intercept and sanitise text-tags on paste

This is a different way of handling bgo#709580, with the change
triggered by #152.

The original problem here is that if you copy-paste within Meld, the
tags that we use to indicate an inline difference get pasted as well, by
GtkTextView/Buffer. This behaviour seems very difficult to opt out of.

The first pass at handling this hacked around the problem by hooking in
to tag apply and, if we were in an action group, skipping it. This
basically worked (but was fragile) until we hit an error situation where
we had unclosed action groups, at which point no tags were ever applied.

This second pass instead hooks in to the textview paste_clipboard vfunc
and requests and sets a text-only representation in the clipboard. This
effectively sanitises the clipboard contents and so... seems to work.
parent 8ff59e8a
......@@ -40,7 +40,6 @@ class MeldBuffer(GtkSource.Buffer):
GtkSource.Buffer.__init__(self)
bind_settings(self)
self.data = MeldBufferData()
self.user_action_count = 0
self.undo_sequence = None
meldsettings.connect('changed', self.on_setting_changed)
self.set_style_scheme(meldsettings.style_scheme)
......@@ -50,27 +49,12 @@ class MeldBuffer(GtkSource.Buffer):
self.set_style_scheme(meldsettings.style_scheme)
def do_begin_user_action(self, *args):
self.user_action_count += 1
if self.undo_sequence:
self.undo_sequence.begin_group()
def do_end_user_action(self, *args):
if self.undo_sequence:
self.undo_sequence.end_group()
self.user_action_count -= 1
def do_apply_tag(self, tag, start, end):
# Filthy, evil, horrible hack. What we're doing here is trying to
# figure out if a tag apply has come from a paste action, in which
# case GtkTextBuffer will 'helpfully' apply the existing tags in the
# copied selection. There appears to be no way to override this
# behaviour, or to hook in to the necessary paste mechanics to just
# request that we only get plain text or something. We're abusing the
# user_action notion here, because we only apply the tags we actually
# want in a callback.
if tag.props.name == 'inline' and self.user_action_count > 0:
return
return GtkSource.Buffer.do_apply_tag(self, tag, start, end)
def get_iter_at_line_or_eof(self, line):
"""Return a Gtk.TextIter at the given line, or the end of the buffer.
......
......@@ -164,6 +164,19 @@ class MeldSourceView(GtkSource.View):
meldsettings.connect('changed', self.on_setting_changed)
def do_paste_clipboard(self, *args):
# This is an awful hack to replace another awful hack. The idea
# here is to sanitise the clipboard contents so that it doesn't
# contain GtkTextTags, by requesting and setting plain text.
def text_received_cb(clipboard, text, *user_data):
clipboard.set_text(text, len(text))
self.get_buffer().paste_clipboard(
clipboard, None, self.get_editable())
clipboard = self.get_clipboard(Gdk.SELECTION_CLIPBOARD)
clipboard.request_text(text_received_cb)
def get_y_for_line_num(self, line):
buf = self.get_buffer()
it = buf.get_iter_at_line(line)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment