[meld] sourceview: Intercept and sanitise text-tags on paste
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] sourceview: Intercept and sanitise text-tags on paste
- Date: Fri, 20 Apr 2018 22:15:31 +0000 (UTC)
commit 02dcbd6d245be488bda4bd57f80a8521c12a7c23
Author: Kai Willadsen <kai willadsen gmail com>
Date: Mon Apr 16 07:28:33 2018 +1000
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.
meld/meldbuffer.py | 16 ----------------
meld/sourceview.py | 13 +++++++++++++
2 files changed, 13 insertions(+), 16 deletions(-)
---
diff --git a/meld/meldbuffer.py b/meld/meldbuffer.py
index 90746475..311cb8c8 100644
--- a/meld/meldbuffer.py
+++ b/meld/meldbuffer.py
@@ -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.
diff --git a/meld/sourceview.py b/meld/sourceview.py
index e4aef776..5226b527 100644
--- a/meld/sourceview.py
+++ b/meld/sourceview.py
@@ -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)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]