[meld/ui-next: 13/35] Initial pass at a SourceMap-based DiffMap replacement#



commit 4613a17915740fc936f5e941df2f98ca4870d671
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sat Nov 24 08:16:36 2018 +1000

    Initial pass at a SourceMap-based DiffMap replacement#

 meld/filediff.py              |  9 +++++---
 meld/resources/ui/filediff.ui | 30 ++++++++++++++++++++++++
 meld/sourceview.py            | 53 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 3 deletions(-)
---
diff --git a/meld/filediff.py b/meld/filediff.py
index ef717157..503af240 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -158,6 +158,9 @@ class FileDiff(Gtk.VBox, MeldDoc):
     scrolledwindow0 = Template.Child()
     scrolledwindow1 = Template.Child()
     scrolledwindow2 = Template.Child()
+    sourcemap0 = Template.Child()
+    sourcemap1 = Template.Child()
+    sourcemap2 = Template.Child()
     statusbar0 = Template.Child()
     statusbar1 = Template.Child()
     statusbar2 = Template.Child()
@@ -211,7 +214,7 @@ class FileDiff(Gtk.VBox, MeldDoc):
         bind_settings(self)
 
         widget_lists = [
-            "file_save_button", "file_toolbar", "fileentry",
+            "sourcemap", "file_save_button", "file_toolbar", "fileentry",
             "linkmap", "msgarea_mgr", "readonlytoggle",
             "scrolledwindow", "textview", "vbox",
             "dummy_toolbar_linkmap", "filelabel_toolitem", "filelabel",
@@ -1987,7 +1990,7 @@ class FileDiff(Gtk.VBox, MeldDoc):
 
         self.num_panes = n
         for widget in (
-                self.vbox[:n] + self.file_toolbar[:n] +
+                self.vbox[:n] + self.file_toolbar[:n] + self.sourcemap[:n] +
                 self.linkmap[:n - 1] + self.dummy_toolbar_linkmap[:n - 1] +
                 self.statusbar[:n] +
                 self.actiongutter[:(n - 1) * 2] +
@@ -1995,7 +1998,7 @@ class FileDiff(Gtk.VBox, MeldDoc):
             widget.show()
 
         for widget in (
-                self.vbox[n:] + self.file_toolbar[n:] +
+                self.vbox[n:] + self.file_toolbar[n:] + self.sourcemap[n:] +
                 self.linkmap[n - 1:] + self.dummy_toolbar_linkmap[n - 1:] +
                 self.statusbar[n:] +
                 self.actiongutter[(n - 1) * 2:] +
diff --git a/meld/resources/ui/filediff.ui b/meld/resources/ui/filediff.ui
index cf0636a1..168079a1 100644
--- a/meld/resources/ui/filediff.ui
+++ b/meld/resources/ui/filediff.ui
@@ -605,6 +605,36 @@
             <property name="top_attach">1</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkBox" id="sourcemap-hbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">horizontal</property>
+            <property name="spacing">2</property>
+            <child>
+              <object class="MeldSourceMap" id="sourcemap0">
+                <property name="view">textview0</property>
+                <property name="visible">True</property>
+              </object>
+            </child>
+            <child>
+              <object class="MeldSourceMap" id="sourcemap1">
+                <property name="view">textview1</property>
+                <property name="visible">True</property>
+              </object>
+            </child>
+            <child>
+              <object class="MeldSourceMap" id="sourcemap2">
+                <property name="view">textview2</property>
+                <property name="visible">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">9</property>
+            <property name="top_attach">1</property>
+          </packing>
+        </child>
         <child>
           <placeholder/>
         </child>
diff --git a/meld/sourceview.py b/meld/sourceview.py
index e4fc6740..62af96bf 100644
--- a/meld/sourceview.py
+++ b/meld/sourceview.py
@@ -398,3 +398,56 @@ class CommitMessageSourceView(GtkSource.View):
         ('insert-spaces-instead-of-tabs', 'insert-spaces-instead-of-tabs'),
         ('draw-spaces', 'draw-spaces'),
     )
+
+
+class MeldSourceMap(GtkSource.Map):
+
+    __gtype_name__ = "MeldSourceMap"
+
+    def do_draw_layer(self, layer, context):
+        if layer != Gtk.TextViewLayer.BELOW_TEXT:
+            return GtkSource.Map.do_draw_layer(self, layer, context)
+
+        def rect_to_lines(rect):
+            return (
+                self.get_line_at_y(rect.y)[0].get_line(),
+                self.get_line_at_y(rect.y + rect.height)[0].get_line(),
+            )
+
+        def get_y_for_line_num(line):
+            buf = self.get_buffer()
+            it = buf.get_iter_at_line(line)
+            y, h = self.get_line_yrange(it)
+            if line >= buf.get_line_count():
+                return y + h
+            return y
+
+        context.save()
+        context.set_line_width(1.0)
+
+        _, clip = Gdk.cairo_get_clip_rectangle(context)
+        bounds = rect_to_lines(clip)
+
+        x = clip.x - 0.5
+        width = clip.width + 1
+
+        parent_view = self.props.view
+        if not hasattr(parent_view, 'chunk_iter'):
+            context.restore()
+            print("yes, but why")
+            return GtkSource.Map.do_draw_layer(self, layer, context)
+
+        # Paint chunk backgrounds and outlines
+        for change in parent_view.chunk_iter(bounds):
+            ypos0 = get_y_for_line_num(change[1])
+            ypos1 = get_y_for_line_num(change[2])
+            height = max(0, ypos1 - ypos0 - 1)
+
+            context.rectangle(x, ypos0 + 0.5, width, height)
+            if change[1] != change[2]:
+                context.set_source_rgba(*parent_view.fill_colors[change[0]])
+                context.fill()
+
+        context.restore()
+
+        return GtkSource.Map.do_draw_layer(self, layer, context)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]