[gitg] Have one single source view for all the hunks



commit 7cfd5a21e83295fc59865d1a41bc38554ec31c33
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Fri Dec 18 22:38:11 2015 +0100

    Have one single source view for all the hunks

 libgitg/Makefile.am                         |    1 -
 libgitg/gitg-diff-view-file.vala            |  441 ++++++++++++++++++++--
 libgitg/gitg-diff-view-hunk.vala            |  542 ---------------------------
 libgitg/gitg-diff-view-lines-renderer.vala  |  172 +++++----
 libgitg/resources/resources.xml             |    1 -
 libgitg/resources/ui/gitg-diff-view-file.ui |   17 +-
 libgitg/resources/ui/gitg-diff-view-hunk.ui |   36 --
 7 files changed, 528 insertions(+), 682 deletions(-)
---
diff --git a/libgitg/Makefile.am b/libgitg/Makefile.am
index ceaa5a2..0dc0830 100644
--- a/libgitg/Makefile.am
+++ b/libgitg/Makefile.am
@@ -63,7 +63,6 @@ libgitg_libgitg_1_0_la_VALASOURCES =                  \
        libgitg/gitg-diff-stat.vala                     \
        libgitg/gitg-diff-view.vala                     \
        libgitg/gitg-diff-view-file.vala                \
-       libgitg/gitg-diff-view-hunk.vala                \
        libgitg/gitg-diff-view-lines-renderer.vala      \
        libgitg/gitg-diff-view-commit-details.vala      \
        libgitg/gitg-diff-view-options.vala             \
diff --git a/libgitg/gitg-diff-view-file.vala b/libgitg/gitg-diff-view-file.vala
index 617eeb9..1cf1d1c 100644
--- a/libgitg/gitg-diff-view-file.vala
+++ b/libgitg/gitg-diff-view-file.vala
@@ -26,15 +26,17 @@ class Gitg.DiffViewFile : Gtk.Grid
        [GtkChild( name = "label_file_header" )]
        private Gtk.Label d_label_file_header;
 
-       [GtkChild( name = "grid_hunks" )]
-       private Gtk.Grid d_grid_hunks;
-
        [GtkChild( name = "diff_stat_file" )]
        private DiffStat d_diff_stat_file;
 
        [GtkChild( name = "revealer_hunks" )]
        private Gtk.Revealer d_revealer_hunks;
 
+       [GtkChild( name = "sourceview_hunks" )]
+       private Gtk.SourceView d_sourceview_hunks;
+
+       private string d_selection_category = "selection";
+
        private bool d_expanded;
 
        public bool expanded
@@ -67,12 +69,30 @@ class Gitg.DiffViewFile : Gtk.Grid
 
        public bool wrap
        {
-               get; set;
+               get { return d_sourceview_hunks.wrap_mode != Gtk.WrapMode.NONE; }
+               set
+               {
+                       if (value)
+                       {
+                               d_sourceview_hunks.wrap_mode = Gtk.WrapMode.WORD_CHAR;
+                       }
+                       else
+                       {
+                               d_sourceview_hunks.wrap_mode = Gtk.WrapMode.NONE;
+                       }
+               }
        }
 
        public int tab_width
        {
-               get; set;
+               get { return (int)d_sourceview_hunks.tab_width; }
+               set
+               {
+                       if (value > 0)
+                       {
+                               d_sourceview_hunks.tab_width = (uint)value;
+                       }
+               }
        }
 
        public int maxlines
@@ -104,6 +124,321 @@ class Gitg.DiffViewFile : Gtk.Grid
                Object(delta: delta, handle_selection: handle_selection);
        }
 
+       private DiffViewLinesRenderer d_old_lines;
+       private DiffViewLinesRenderer d_new_lines;
+       private DiffViewLinesRenderer d_sym_lines;
+
+       construct
+       {
+               var gutter = d_sourceview_hunks.get_gutter(Gtk.TextWindowType.LEFT);
+
+               d_old_lines = new DiffViewLinesRenderer(DiffViewLinesRenderer.Style.OLD);
+               d_new_lines = new DiffViewLinesRenderer(DiffViewLinesRenderer.Style.NEW);
+               d_sym_lines = new DiffViewLinesRenderer(DiffViewLinesRenderer.Style.SYMBOL);
+
+               this.bind_property("maxlines", d_old_lines, "maxlines", BindingFlags.DEFAULT | 
BindingFlags.SYNC_CREATE);
+               this.bind_property("maxlines", d_new_lines, "maxlines", BindingFlags.DEFAULT | 
BindingFlags.SYNC_CREATE);
+
+               d_old_lines.xpad = 8;
+               d_new_lines.xpad = 8;
+               d_sym_lines.xpad = 6;
+
+               gutter.insert(d_old_lines, 0);
+               gutter.insert(d_new_lines, 1);
+               gutter.insert(d_sym_lines, 2);
+
+               if (handle_selection)
+               {
+                       d_sourceview_hunks.button_press_event.connect(button_press_event_on_view);
+                       d_sourceview_hunks.motion_notify_event.connect(motion_notify_event_on_view);
+                       d_sourceview_hunks.button_release_event.connect(button_release_event_on_view);
+
+                       d_sourceview_hunks.get_style_context().add_class("handle-selection");
+
+                       d_sourceview_hunks.realize.connect(update_cursor);
+                       d_sourceview_hunks.notify["state-flags"].connect(update_cursor);
+               }
+
+               d_sourceview_hunks.set_border_window_size(Gtk.TextWindowType.TOP, 1);
+
+               var settings = Gtk.Settings.get_default();
+               settings.notify["gtk-application-prefer-dark-theme"].connect(update_theme);
+               update_theme();
+       }
+
+       private void update_cursor()
+       {
+               var window = d_sourceview_hunks.get_window(Gtk.TextWindowType.TEXT);
+
+               if (window == null)
+               {
+                       return;
+               }
+
+               var cursor = new Gdk.Cursor.for_display(d_sourceview_hunks.get_display(), 
Gdk.CursorType.LEFT_PTR);
+               window.set_cursor(cursor);
+       }
+
+       private void update_theme()
+       {
+               var selection_attributes = new Gtk.SourceMarkAttributes();
+               var header_attributes = new Gtk.SourceMarkAttributes();
+               var added_attributes = new Gtk.SourceMarkAttributes();
+               var removed_attributes = new Gtk.SourceMarkAttributes();
+
+               var settings = Gtk.Settings.get_default();
+
+               if (settings.gtk_application_prefer_dark_theme)
+               {
+                       selection_attributes.background = Gdk.RGBA() { red = 52.0 / 255.0, green = 101.0 / 
255.0, blue = 164.0 / 255.0, alpha = 1.0 };
+                       header_attributes.background = Gdk.RGBA() { red = 224.0 / 255.0, green = 239.0 / 
255.0, blue = 1.0, alpha = 1.0 };
+                       added_attributes.background = Gdk.RGBA() { red = 164.0 / 255.0, green = 0.0, blue = 
0.0, alpha = 1.0 };
+                       removed_attributes.background = Gdk.RGBA() { red = 78.0 / 255.0, green = 154.0 / 
255.0, blue = 6.0 / 255.0, alpha = 1.0 };
+               }
+               else
+               {
+                       selection_attributes.background = Gdk.RGBA() { red = 168.0 / 255.0, green = 207.0 / 
255.0, blue = 214.0 / 255.0, alpha = 1.0 };
+                       header_attributes.background = Gdk.RGBA() { red = 224.0 / 255.0, green = 239.0 / 
255.0, blue = 1.0, alpha = 1.0 };
+                       added_attributes.background = Gdk.RGBA() { red = 220.0 / 255.0, green = 1.0, blue = 
220.0 / 255.0, alpha = 1.0 };
+                       removed_attributes.background = Gdk.RGBA() { red = 1.0, green = 220.0 / 255.0, blue = 
220.0 / 255.0, alpha = 1.0 };
+               }
+
+               d_sourceview_hunks.set_mark_attributes(d_selection_category, selection_attributes, 0);
+               d_sourceview_hunks.set_mark_attributes("header", header_attributes, 0);
+               d_sourceview_hunks.set_mark_attributes("added", added_attributes, 0);
+               d_sourceview_hunks.set_mark_attributes("removed", removed_attributes, 0);
+       }
+
+       private bool get_line_selected(Gtk.TextIter iter)
+       {
+               var text_view = d_sourceview_hunks as Gtk.TextView;
+               Gtk.TextIter start = iter;
+
+               start.set_line_offset(0);
+               var buffer = text_view.get_buffer() as Gtk.SourceBuffer;
+
+               return buffer.get_source_marks_at_iter(start, d_selection_category) != null;
+       }
+
+       private bool get_line_is_diff(Gtk.TextIter iter)
+       {
+               var text_view = d_sourceview_hunks as Gtk.TextView;
+               Gtk.TextIter start = iter;
+
+               start.set_line_offset(0);
+               var buffer = text_view.get_buffer() as Gtk.SourceBuffer;
+
+               return (buffer.get_source_marks_at_iter(start, "added") != null) ||
+                      (buffer.get_source_marks_at_iter(start, "removed") != null);
+       }
+
+       private bool get_iter_from_pointer_position(out Gtk.TextIter iter)
+       {
+               var text_view = d_sourceview_hunks as Gtk.TextView;
+               var win = text_view.get_window(Gtk.TextWindowType.TEXT);
+               int x, y, width, height;
+
+               width = win.get_width();
+               height = win.get_height();
+
+               var pointer = Gdk.Display.get_default().get_device_manager().get_client_pointer();
+               win.get_device_position(pointer, out x, out y, null);
+
+               if (x < 0 || y < 0 || x > width || y > height)
+               {
+                       return false;
+               }
+
+               int win_x, win_y;
+               text_view.window_to_buffer_coords(Gtk.TextWindowType.TEXT, x, y, out win_x, out win_y);
+
+               text_view.get_iter_at_location(out iter, win_x, win_y);
+
+               return true;
+       }
+
+       private void select_range(Gtk.TextIter start, Gtk.TextIter end)
+       {
+               var text_view = d_sourceview_hunks as Gtk.TextView;
+               var buffer = text_view.get_buffer() as Gtk.SourceBuffer;
+
+               start.order(end);
+
+               while (start.get_line() <= end.get_line())
+               {
+                       start.set_line_offset(0);
+
+                       if (get_line_is_diff(start))
+                       {
+                               buffer.create_source_mark(null, d_selection_category, start);
+                       }
+
+                       if (!start.forward_line())
+                       {
+                               break;
+                       }
+               }
+       }
+
+       private void deselect_range(Gtk.TextIter start, Gtk.TextIter end)
+       {
+               var text_view = d_sourceview_hunks as Gtk.TextView;
+               var buffer = text_view.get_buffer() as Gtk.SourceBuffer;
+
+               Gtk.TextIter real_start, real_end;
+
+               real_start = start;
+               real_start.set_line_offset(0);
+
+               real_end = end;
+               real_end.forward_to_line_end();
+
+               buffer.remove_source_marks(real_start, real_end, d_selection_category);
+       }
+
+       private bool d_is_selecting;
+       private bool d_is_deselecting;
+       private Gtk.TextMark d_start_selection_mark;
+       private Gtk.TextMark d_end_selection_mark;
+
+       private bool button_press_event_on_view(Gdk.EventButton event)
+       {
+               if (event.button != 1)
+               {
+                       return false;
+               }
+
+               Gtk.TextIter iter;
+               if (!get_iter_from_pointer_position(out iter))
+               {
+                       return false;
+               }
+
+               if (get_line_selected(iter))
+               {
+                       d_is_deselecting = true;
+                       deselect_range(iter, iter);
+               }
+               else
+               {
+                       d_is_selecting = true;
+                       select_range(iter, iter);
+               }
+
+               var text_view = d_sourceview_hunks as Gtk.TextView;
+               var buffer = text_view.get_buffer();
+
+               d_start_selection_mark = buffer.create_mark(null, iter, false);
+               d_end_selection_mark = buffer.create_mark(null, iter, false);
+
+               return false;
+       }
+
+       private bool motion_notify_event_on_view(Gdk.EventMotion event)
+       {
+               if (!d_is_selecting && !d_is_deselecting)
+               {
+                       return false;
+               }
+
+               Gtk.TextIter iter;
+               if (!get_iter_from_pointer_position(out iter))
+               {
+                       return false;
+               }
+
+               var text_view = d_sourceview_hunks as Gtk.TextView;
+               var buffer = text_view.get_buffer();
+
+               Gtk.TextIter start, end, current;
+
+               current = iter;
+
+               buffer.get_iter_at_mark(out start, d_start_selection_mark);
+               start.order(current);
+
+               if (d_is_selecting)
+               {
+                       select_range(start, current);
+               }
+               else
+               {
+                       deselect_range(start, current);
+               }
+
+               buffer.get_iter_at_mark(out end, d_end_selection_mark);
+               if (!end.in_range(start, current))
+               {
+                       start = end;
+                       current = iter;
+
+                       start.order(current);
+
+                       if (d_is_selecting)
+                       {
+                               deselect_range(start, current);
+                       }
+                       else
+                       {
+                               select_range(start, current);
+                       }
+               }
+
+               buffer.move_mark(d_end_selection_mark, iter);
+
+               return false;
+       }
+
+       private void update_has_selection()
+       {
+               var text_view = d_sourceview_hunks as Gtk.TextView;
+               var buffer = text_view.get_buffer();
+
+               Gtk.TextIter iter;
+               buffer.get_start_iter(out iter);
+
+               bool something_selected = false;
+
+               if (get_line_selected(iter))
+               {
+                       something_selected = true;
+               }
+               else
+               {
+                       something_selected = (buffer as Gtk.SourceBuffer).forward_iter_to_source_mark(iter, 
d_selection_category);
+               }
+
+               if (something_selected != d_has_selection)
+               {
+                       d_has_selection = something_selected;
+                       notify_property("has-selection");
+               }
+       }
+
+       private bool button_release_event_on_view(Gdk.EventButton event)
+       {
+               if (event.button != 1)
+               {
+                       return false;
+               }
+
+               d_is_selecting = false;
+               d_is_deselecting = false;
+
+               var text_view = d_sourceview_hunks as Gtk.TextView;
+               var buffer = text_view.get_buffer();
+
+               buffer.delete_mark(d_start_selection_mark);
+               d_start_selection_mark = null;
+
+               buffer.delete_mark(d_end_selection_mark);
+               d_end_selection_mark = null;
+
+               update_has_selection();
+
+               return false;
+       }
+
        protected override void constructed()
        {
                base.constructed();
@@ -130,41 +465,91 @@ class Gitg.DiffViewFile : Gtk.Grid
                d_expander.bind_property("expanded", this, "expanded", BindingFlags.BIDIRECTIONAL);
        }
 
-       private void on_selection_changed()
+       public void add_hunk(Ggit.DiffHunk hunk, Gee.ArrayList<Ggit.DiffLine> lines)
        {
-               bool something_selected = false;
+               var buffer = d_sourceview_hunks.buffer as Gtk.SourceBuffer;
+
+               /* Diff hunk */
+               var h = hunk.get_header();
+               var pos = h.last_index_of("@@");
 
-               foreach (var child in d_grid_hunks.get_children())
+               if (pos >= 0)
                {
-                       if ((child as Gitg.DiffViewHunk).has_selection)
-                       {
-                               something_selected = true;
-                               break;
-                       }
+                       h = h.substring(pos + 2).chug();
                }
 
-               if (d_has_selection != something_selected)
+               h = h.chomp();
+
+               Gtk.TextIter iter;
+               buffer.get_end_iter(out iter);
+               if (!iter.is_start())
                {
-                       d_has_selection = something_selected;
-                       notify_property("has-selection");
+                       buffer.insert(ref iter, "\n", 1);
                }
-       }
 
-       public void add_hunk(Ggit.DiffHunk hunk, Gee.ArrayList<Ggit.DiffLine> lines)
-       {
-               var widget = new Gitg.DiffViewHunk(hunk, lines, handle_selection);
-               widget.show();
+               iter.set_line_offset(0);
+               int line_header = iter.get_line();
+               buffer.create_source_mark(null, "header", iter);
+
+               var header = @"@@ -$(hunk.get_old_start()),$(hunk.get_old_lines()) 
+$(hunk.get_new_start()),$(hunk.get_new_lines()) @@ $h\n";
+               buffer.insert(ref iter, header, -1);
+
+               /* Diff Content */
+               var content = new StringBuilder();
+
+               for (var i = 0; i < lines.size; i++)
+               {
+                       var line = lines[i];
+                       var text = line.get_text();
+
+                       switch (line.get_origin())
+                       {
+                               case Ggit.DiffLineType.ADDITION:
+                                       break;
+                               case Ggit.DiffLineType.DELETION:
+                                       break;
+                               case Ggit.DiffLineType.CONTEXT_EOFNL:
+                               case Ggit.DiffLineType.ADD_EOFNL:
+                               case Ggit.DiffLineType.DEL_EOFNL:
+                                       text = text.substring(1);
+                                       break;
+                       }
 
-               d_diff_stat_file.added += widget.added;
-               d_diff_stat_file.removed += widget.removed;
+                       if (i == lines.size - 1 && text.length > 0 && text[text.length - 1] == '\n')
+                       {
+                               text = text.slice(0, text.length - 1);
+                       }
+
+                       content.append(text);
+               }
+
+               buffer.insert(ref iter, (string)content.data, -1);
+
+               d_old_lines.add_hunk(line_header, iter.get_line(), hunk, lines);
+               d_new_lines.add_hunk(line_header, iter.get_line(), hunk, lines);
+               d_sym_lines.add_hunk(line_header, iter.get_line(), hunk, lines);
 
-               d_grid_hunks.add(widget);
+               for (var i = 0; i < lines.size; i++)
+               {
+                       var line = lines[i];
+                       string? category = null;
 
-               this.bind_property("maxlines", widget, "maxlines", BindingFlags.DEFAULT | 
BindingFlags.SYNC_CREATE);
-               this.bind_property("wrap", widget, "wrap", BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE);
-               this.bind_property("tab-width", widget, "tab-width", BindingFlags.DEFAULT | 
BindingFlags.SYNC_CREATE);
+                       switch (line.get_origin())
+                       {
+                               case Ggit.DiffLineType.ADDITION:
+                                       category = "added";
+                                       break;
+                               case Ggit.DiffLineType.DELETION:
+                                       category = "removed";
+                                       break;
+                       }
 
-               widget.notify["has-selection"].connect(on_selection_changed);
+                       if (category != null)
+                       {
+                               buffer.get_iter_at_line(out iter, line_header + i);
+                               buffer.create_source_mark(null, category, iter);
+                       }
+               }
 
                sensitive = true;
        }
diff --git a/libgitg/gitg-diff-view-lines-renderer.vala b/libgitg/gitg-diff-view-lines-renderer.vala
index 7b162bf..0938b44 100644
--- a/libgitg/gitg-diff-view-lines-renderer.vala
+++ b/libgitg/gitg-diff-view-lines-renderer.vala
@@ -32,17 +32,14 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
 
        private ulong d_view_style_updated_id;
 
-       private string[] d_line_infos;
-
-       public Ggit.DiffHunk hunk
+       private struct HunkInfo
        {
-               get; construct set;
+               int start;
+               int end;
+               string[] line_infos;
        }
 
-       public Gee.ArrayList<Ggit.DiffLine> lines
-       {
-               get; construct set;
-       }
+       private Gee.HashMap<Ggit.DiffHunk, HunkInfo?> d_hunks_map;
 
        public Style style
        {
@@ -66,64 +63,17 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
                }
        }
 
-       public DiffViewLinesRenderer(Ggit.DiffHunk hunk, Gee.ArrayList<Ggit.DiffLine> lines, Style style)
+       public DiffViewLinesRenderer(Style style)
        {
-               Object(hunk: hunk, lines: lines, style: style);
-               set_alignment(1.0f, 0.5f);
+               Object(style: style);
        }
 
-       protected override void constructed()
+       construct
        {
-               calculate_num_digits();
-               precalculate_line_strings();
-       }
-
-       private void precalculate_line_strings()
-       {
-               var oldn = hunk.get_old_start();
-               var newn = hunk.get_new_start();
-
-               var lns = lines;
-
-               d_line_infos = new string[lns.size];
-
-               for (var i = 0; i < lns.size; i++)
-               {
-                       var line = lns[i];
-                       var origin = line.get_origin();
-
-                       string ltext = "";
-
-                       switch (style)
-                       {
-                       case Style.NEW:
-                               if (origin == Ggit.DiffLineType.CONTEXT || origin == 
Ggit.DiffLineType.ADDITION)
-                               {
-                                       ltext = d_num_digits_fmts.printf(newn);
-                                       newn++;
-                               }
-                               break;
-                       case Style.OLD:
-                               if (origin == Ggit.DiffLineType.CONTEXT || origin == 
Ggit.DiffLineType.DELETION)
-                               {
-                                       ltext = d_num_digits_fmts.printf(oldn);
-                                       oldn++;
-                               }
-                               break;
-                       case Style.SYMBOL:
-                               if (origin == Ggit.DiffLineType.ADDITION)
-                               {
-                                       ltext = "+";
-                               }
-                               else if (origin == Ggit.DiffLineType.DELETION)
-                               {
-                                       ltext = "-";
-                               }
-                               break;
-                       }
+               d_hunks_map = new Gee.HashMap<Ggit.DiffHunk, HunkInfo?>();
 
-                       d_line_infos[i] = ltext;
-               }
+               set_alignment(1.0f, 0.5f);
+               calculate_num_digits();
        }
 
        protected Gtk.TextBuffer buffer
@@ -134,14 +84,24 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
        protected override void query_data(Gtk.TextIter start, Gtk.TextIter end, 
Gtk.SourceGutterRendererState state)
        {
                var line = start.get_line();
+               HunkInfo? info = null;
 
-               if (line >= d_line_infos.length)
+               foreach (var i in d_hunks_map.values)
+               {
+                       if (line >= i.start && line <= i.end)
+                       {
+                               info = i;
+                               break;
+                       }
+               }
+
+               if (info == null || line >= info.line_infos.length)
                {
                        set_text("", -1);
                }
                else
                {
-                       set_text(d_line_infos[start.get_line()], -1);
+                       set_text(info.line_infos[start.get_line() - info.start], -1);
                }
        }
 
@@ -184,18 +144,21 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
 
                if (style == Style.OLD || style == Style.NEW)
                {
-                       var oldn = hunk.get_old_start() + hunk.get_old_lines();
-                       var newn = hunk.get_new_start() + hunk.get_new_lines();
+                       foreach (var hunk in d_hunks_map.keys)
+                       {
+                               var oldn = hunk.get_old_start() + hunk.get_old_lines();
+                               var newn = hunk.get_new_start() + hunk.get_new_lines();
 
-                       var num = int.max(int.max(oldn, newn), d_maxlines);
+                               var num = int.max(int.max(oldn, newn), d_maxlines);
 
-                       while (num > 0)
-                       {
-                               ++num_digits;
-                               num /= 10;
-                       }
+                               while (num > 0)
+                               {
+                                       ++num_digits;
+                                       num /= 10;
+                               }
 
-                       d_num_digits = int.max(2, num_digits);
+                               d_num_digits = int.max(2, num_digits);
+                       }
                }
                else
                {
@@ -235,6 +198,71 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
                        ctx.restore();
                }
        }
+
+       private string[] precalculate_line_strings(Ggit.DiffHunk hunk, Gee.ArrayList<Ggit.DiffLine> lines)
+       {
+               var oldn = hunk.get_old_start();
+               var newn = hunk.get_new_start();
+
+               var lns = lines;
+
+               var line_infos = new string[lns.size];
+
+               for (var i = 0; i < lns.size; i++)
+               {
+                       var line = lns[i];
+                       var origin = line.get_origin();
+
+                       string ltext = "";
+
+                       switch (style)
+                       {
+                       case Style.NEW:
+                               if (origin == Ggit.DiffLineType.CONTEXT || origin == 
Ggit.DiffLineType.ADDITION)
+                               {
+                                       ltext = d_num_digits_fmts.printf(newn);
+                                       newn++;
+                               }
+                               break;
+                       case Style.OLD:
+                               if (origin == Ggit.DiffLineType.CONTEXT || origin == 
Ggit.DiffLineType.DELETION)
+                               {
+                                       ltext = d_num_digits_fmts.printf(oldn);
+                                       oldn++;
+                               }
+                               break;
+                       case Style.SYMBOL:
+                               if (origin == Ggit.DiffLineType.ADDITION)
+                               {
+                                       ltext = "+";
+                               }
+                               else if (origin == Ggit.DiffLineType.DELETION)
+                               {
+                                       ltext = "-";
+                               }
+                               break;
+                       }
+
+                       line_infos[i] = ltext;
+               }
+
+               return line_infos;
+       }
+
+       public void add_hunk(int buffer_line_start, int buffer_line_end, Ggit.DiffHunk hunk, 
Gee.ArrayList<Ggit.DiffLine> lines)
+       {
+               HunkInfo info = HunkInfo();
+
+               calculate_num_digits();
+
+               info.start = buffer_line_start;
+               info.end = buffer_line_end;
+               info.line_infos = precalculate_line_strings(hunk, lines);
+
+               d_hunks_map[hunk] = info;
+
+               recalculate_size();
+       }
 }
 
 // ex:ts=4 noet
diff --git a/libgitg/resources/resources.xml b/libgitg/resources/resources.xml
index 0f520f4..f946de7 100644
--- a/libgitg/resources/resources.xml
+++ b/libgitg/resources/resources.xml
@@ -5,7 +5,6 @@
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-authentication-dialog.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-file.ui</file>
-    <file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-hunk.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-options.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-commit-details.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/gitg-sidebar.ui</file>
diff --git a/libgitg/resources/ui/gitg-diff-view-file.ui b/libgitg/resources/ui/gitg-diff-view-file.ui
index fed5076..0e379eb 100644
--- a/libgitg/resources/ui/gitg-diff-view-file.ui
+++ b/libgitg/resources/ui/gitg-diff-view-file.ui
@@ -56,13 +56,26 @@
         <property name="can_focus">False</property>
         <property name="transition_type">slide-down</property>
         <child>
-          <object class="GtkGrid" id="grid_hunks">
+          <object class="GtkSourceView" id="sourceview_hunks">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
+            <property name="show_line_numbers">False</property>
+            <property name="editable">False</property>
+            <property name="cursor_visible">False</property>
+            <property name="monospace">True</property>
+            <property name="hexpand">True</property>
+            <property name="pixels_above_lines">1</property>
+            <property name="pixels_below_lines">1</property>
+            <property name="left_margin">6</property>
+            <property name="right_margin">6</property>
+            <property name="buffer">buffer</property>
           </object>
         </child>
       </object>
     </child>
   </template>
+  <object class="GtkSourceBuffer" id="buffer">
+    <property name="highlight_matching_brackets">False</property>
+    <property name="implicit_trailing_newline">False</property>
+  </object>
 </interface>


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