[meld] Use line offsets from textview for drawing DiffMap (closes bgo#589540)
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] Use line offsets from textview for drawing DiffMap (closes bgo#589540)
- Date: Sat, 26 Mar 2011 08:26:09 +0000 (UTC)
commit 63744c06c58d48b00255f82b5f10af16ded38958
Author: Kai Willadsen <kai willadsen gmail com>
Date: Mon Aug 30 08:55:18 2010 +1000
Use line offsets from textview for drawing DiffMap (closes bgo#589540)
Previously, we assumed a constant line height, which breaks badly when
line wrapping is enabled. This commit changes to ask our textviews for
offsets, which is slower but reliable.
meld/diffmap.py | 23 +++++------------------
meld/filediff.py | 27 ++++++++++++++++++++++++---
2 files changed, 29 insertions(+), 21 deletions(-)
---
diff --git a/meld/diffmap.py b/meld/diffmap.py
index 8460d8b..1fac0b3 100644
--- a/meld/diffmap.py
+++ b/meld/diffmap.py
@@ -39,25 +39,20 @@ class DiffMap(gtk.DrawingArea):
self._h_offset = 0
self._scroll_y = 0
self._scroll_height = 0
- self._num_lines = 0
- def setup(self, scrollbar, textbuffer, change_chunk_fn):
+ def setup(self, scrollbar, change_chunk_fn):
for (o, h) in self._handlers:
o.disconnect(h)
self._scrolladj = scrollbar.get_adjustment()
self.on_scrollbar_style_set(scrollbar, None)
self.on_scrollbar_size_allocate(scrollbar, scrollbar.allocation)
- self.on_textbuffer_changed(textbuffer)
scroll_style_hid = scrollbar.connect("style-set",
self.on_scrollbar_style_set)
scroll_size_hid = scrollbar.connect("size-allocate",
self.on_scrollbar_size_allocate)
- buffer_changed_hid = textbuffer.connect("changed",
- self.on_textbuffer_changed)
self._handlers = [(scrollbar, scroll_style_hid),
- (scrollbar, scroll_size_hid),
- (textbuffer, buffer_changed_hid)]
+ (scrollbar, scroll_size_hid)]
self._difffunc = change_chunk_fn
self.queue_draw()
@@ -84,15 +79,8 @@ class DiffMap(gtk.DrawingArea):
self._scroll_height = allocation.height
self.queue_draw()
- def on_textbuffer_changed(self, textbuffer):
- num_lines = textbuffer.get_line_count()
- if num_lines != self._num_lines:
- self._num_lines = num_lines
- self.queue_draw()
-
def do_expose_event(self, event):
height = self._scroll_height - self._h_offset - 1
- scale = float(height) / self._num_lines
y_start = self._scroll_y - self.allocation.y + self._y_offset + 1
xpad = self.style_get_property('x-padding')
x0 = xpad
@@ -110,10 +98,9 @@ class DiffMap(gtk.DrawingArea):
"delete": (0.75686274509803919, 1.0, 0.75686274509803919)}
darken = lambda color: [x * 0.8 for x in color]
- for c in self._difffunc():
- color = ctab[c[0]]
- y0 = round(scale * c[1]) - 0.5
- y1 = round(scale * c[2]) - 0.5
+ for c, y0, y1 in self._difffunc():
+ color = ctab[c]
+ y0, y1 = round(y0 * height) - 0.5, round(y1 * height) - 0.5
context.set_source_rgb(*color)
context.rectangle(x0, y0, x1, int(y1 - y0))
context.fill_preserve()
diff --git a/meld/filediff.py b/meld/filediff.py
index e9252f4..d79fcfd 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -637,6 +637,11 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
elif key == "edit_wrap_lines":
for t in self.textview:
t.set_wrap_mode(self.prefs.edit_wrap_lines)
+ # FIXME: On changing wrap mode, we get one redraw using cached
+ # coordinates, followed by a second redraw (e.g., on refocus) with
+ # correct coordinates. Overly-aggressive textview lazy calculation?
+ self.diffmap0.queue_draw()
+ self.diffmap1.queue_draw()
elif key == "spaces_instead_of_tabs":
for t in self.textview:
t.set_insert_spaces_instead_of_tabs(value)
@@ -1375,11 +1380,27 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
self.actiongroup.get_action("MakePatch").set_sensitive(n > 1)
- def chunk_change_fn(i):
- return lambda: self.linediffer.single_changes(i)
+ def coords_iter(i):
+ buf_index = 2 if i == 1 and self.num_panes == 3 else i
+ get_end_iter = self.textbuffer[buf_index].get_end_iter
+ get_iter_at_line = self.textbuffer[buf_index].get_iter_at_line
+ get_line_yrange = self.textview[buf_index].get_line_yrange
+
+ def coords_by_chunk():
+ y, h = get_line_yrange(get_end_iter())
+ max_y = float(y + h)
+ for c in self.linediffer.single_changes(i):
+ y0, _ = get_line_yrange(get_iter_at_line(c[1]))
+ if c[1] == c[2]:
+ y, h = y0, 0
+ else:
+ y, h = get_line_yrange(get_iter_at_line(c[2] - 1))
+ yield c[0], y0 / max_y, (y + h) / max_y
+ return coords_by_chunk
+
for (w, i) in zip(self.diffmap, (0, self.num_panes - 1)):
scroll = self.scrolledwindow[i].get_vscrollbar()
- w.setup(scroll, self.textbuffer[i], chunk_change_fn(i))
+ w.setup(scroll, coords_iter(i))
for i in range(self.num_panes):
if self.bufferdata[i].modified:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]