[gitg/wip/albfan/gitattributes-textconv: 5/6] Side by side diff text renderers
- From: Alberto Fanjul <albfan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gitg/wip/albfan/gitattributes-textconv: 5/6] Side by side diff text renderers
- Date: Mon, 27 Dec 2021 09:40:42 +0000 (UTC)
commit adfc2fbdda925687e6829c2dac80e67eeb3403e3
Author: Xiaoguang Wang <xwang suse com>
Date: Fri Nov 19 23:47:12 2021 +0100
Side by side diff text renderers
.../gitg-diff-view-file-renderer-text-split.vala | 145 +++++++++++++
.../gitg-diff-view-file-renderer-text-three.vala | 158 ++++++++++++++
libgitg/gitg-diff-view-file-renderer-text.vala | 240 ++++++++++++++++-----
libgitg/gitg-diff-view-file-renderer-textable.vala | 28 +++
libgitg/gitg-diff-view-file.vala | 81 +++++--
libgitg/gitg-diff-view-lines-renderer.vala | 78 +++++--
libgitg/gitg-diff-view.vala | 40 ++--
libgitg/meson.build | 5 +
libgitg/resources/resources.xml | 2 +
.../ui/gitg-diff-view-file-renderer-text-split.ui | 35 +++
.../ui/gitg-diff-view-file-renderer-text-three.ui | 44 ++++
libgitg/resources/ui/gitg-diff-view-file.ui | 2 -
12 files changed, 749 insertions(+), 109 deletions(-)
---
diff --git a/libgitg/gitg-diff-view-file-renderer-text-split.vala
b/libgitg/gitg-diff-view-file-renderer-text-split.vala
new file mode 100644
index 00000000..53cc469e
--- /dev/null
+++ b/libgitg/gitg-diff-view-file-renderer-text-split.vala
@@ -0,0 +1,145 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2016 - Jesse van den Kieboom
+ *
+ * gitg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gitg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-diff-view-file-renderer-text-split.ui")]
+class Gitg.DiffViewFileRendererTextSplit : Gtk.Box, DiffSelectable, DiffViewFileRenderer,
DiffViewFileRendererTextable
+{
+ [GtkChild( name = "scroll_left" )]
+ private unowned Gtk.ScrolledWindow d_scroll_left;
+ [GtkChild( name = "scroll_right" )]
+ private unowned Gtk.ScrolledWindow d_scroll_right;
+
+ private Gitg.DiffViewFileRendererText d_renderer_left;
+ private Gitg.DiffViewFileRendererText d_renderer_right;
+
+ public DiffViewFileInfo info { get; construct set; }
+
+ public Ggit.DiffDelta? delta
+ {
+ get { return info.delta; }
+ }
+
+ public Repository? repository
+ {
+ get { return info.repository; }
+ }
+
+ public bool wrap_lines
+ {
+ get { return d_renderer_left.wrap_mode != Gtk.WrapMode.NONE; }
+ set
+ {
+ if (value)
+ {
+ d_renderer_left.wrap_mode = Gtk.WrapMode.WORD_CHAR;
+ d_renderer_right.wrap_mode = Gtk.WrapMode.WORD_CHAR;
+ }
+ else
+ {
+ d_renderer_left.wrap_mode = Gtk.WrapMode.NONE;
+ d_renderer_right.wrap_mode = Gtk.WrapMode.NONE;
+ }
+ }
+ }
+
+ public new int tab_width
+ {
+ get
+ {
+ return (int)d_renderer_left.get_tab_width();
+ }
+ set
+ {
+ d_renderer_left.set_tab_width((uint)value);
+ d_renderer_right.set_tab_width((uint)value);
+ }
+ }
+
+ public int maxlines
+ {
+ get
+ {
+ return (int)d_renderer_left.maxlines;
+ }
+ set
+ {
+ d_renderer_left.maxlines = value;
+ d_renderer_right.maxlines = value;
+ }
+ }
+
+ public bool highlight
+ {
+ get { return d_renderer_left.highlight; }
+
+ construct set
+ {
+ if (highlight != value)
+ {
+ d_renderer_left.highlight = value;
+ d_renderer_right.highlight = value;
+ }
+ }
+ }
+
+ public DiffViewFileRendererTextSplit(DiffViewFileInfo info, bool handle_selection)
+ {
+ Object(info: info);
+ d_renderer_left = new Gitg.DiffViewFileRendererText(info, handle_selection,
DiffViewFileRendererText.Style.OLD);
+ d_renderer_right = new Gitg.DiffViewFileRendererText(info, handle_selection,
DiffViewFileRendererText.Style.NEW);
+ d_scroll_left.add(d_renderer_left);
+ d_scroll_right.add(d_renderer_right);
+ }
+
+ construct
+ {
+ //can_select = d_renderer_left.can_select() || d_renderer_right.can_select();
+ can_select = false;
+ }
+
+ public void add_hunk(Ggit.DiffHunk hunk, Gee.ArrayList<Ggit.DiffLine> lines)
+ {
+ d_renderer_left.add_hunk(hunk, lines);
+ d_renderer_right.add_hunk(hunk, lines);
+ }
+
+ public bool has_selection
+ {
+ get
+ {
+ //return d_renderer_left.has_selection() || d_renderer_right.has_selection();
+ return false;
+ }
+ }
+
+ public bool can_select { get; construct set; }
+
+ public PatchSet selection
+ {
+ owned get
+ {
+ /*if (d_renderer_left.has_selection())
+ return d_renderer_left.get_selection();
+ if (d_renderer_right.has_selection())
+ return d_renderer_right.get_selection();
+ */
+ return new PatchSet();
+ }
+ }
+}
diff --git a/libgitg/gitg-diff-view-file-renderer-text-three.vala
b/libgitg/gitg-diff-view-file-renderer-text-three.vala
new file mode 100644
index 00000000..755ba10b
--- /dev/null
+++ b/libgitg/gitg-diff-view-file-renderer-text-three.vala
@@ -0,0 +1,158 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2016 - Jesse van den Kieboom
+ *
+ * gitg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gitg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-diff-view-file-renderer-text-three.ui")]
+class Gitg.DiffViewFileRendererTextThree : Gtk.Box, DiffSelectable, DiffViewFileRenderer,
DiffViewFileRendererTextable
+{
+ [GtkChild( name = "scroll_left" )]
+ private unowned Gtk.ScrolledWindow d_scroll_left;
+ [GtkChild( name = "scroll_center" )]
+ private unowned Gtk.ScrolledWindow d_scroll_center;
+ [GtkChild( name = "scroll_right" )]
+ private unowned Gtk.ScrolledWindow d_scroll_right;
+
+
+ private Gitg.DiffViewFileRendererText d_renderer_left;
+ private Gitg.DiffViewFileRendererText d_renderer_center;
+ private Gitg.DiffViewFileRendererText d_renderer_right;
+
+ public DiffViewFileInfo info { get; construct set; }
+
+ public Ggit.DiffDelta? delta
+ {
+ get { return info.delta; }
+ }
+
+ public Repository? repository
+ {
+ get { return info.repository; }
+ }
+
+ public bool wrap_lines
+ {
+ get { return d_renderer_left.wrap_mode != Gtk.WrapMode.NONE; }
+ set
+ {
+ if (value)
+ {
+ d_renderer_left.wrap_mode = Gtk.WrapMode.WORD_CHAR;
+ d_renderer_center.wrap_mode = Gtk.WrapMode.WORD_CHAR;
+ d_renderer_right.wrap_mode = Gtk.WrapMode.WORD_CHAR;
+ }
+ else
+ {
+ d_renderer_left.wrap_mode = Gtk.WrapMode.NONE;
+ d_renderer_center.wrap_mode = Gtk.WrapMode.NONE;
+ d_renderer_right.wrap_mode = Gtk.WrapMode.NONE;
+ }
+ }
+ }
+
+ public new int tab_width
+ {
+ get
+ {
+ return (int)d_renderer_left.get_tab_width();
+ }
+ set
+ {
+ d_renderer_left.set_tab_width((uint)value);
+ d_renderer_center.set_tab_width((uint)value);
+ d_renderer_right.set_tab_width((uint)value);
+ }
+ }
+
+ public int maxlines
+ {
+ get
+ {
+ return (int)d_renderer_left.maxlines;
+ }
+ set
+ {
+ d_renderer_left.maxlines = value;
+ d_renderer_center.maxlines = value;
+ d_renderer_right.maxlines = value;
+ }
+ }
+
+ public bool highlight
+ {
+ get { return d_renderer_left.highlight; }
+
+ construct set
+ {
+ if (highlight != value)
+ {
+ d_renderer_left.highlight = value;
+ d_renderer_center.highlight = value;
+ d_renderer_right.highlight = value;
+ }
+ }
+ }
+
+ public DiffViewFileRendererTextThree(DiffViewFileInfo info, bool handle_selection)
+ {
+ Object(info: info);
+ d_renderer_left = new Gitg.DiffViewFileRendererText(info, handle_selection,
DiffViewFileRendererText.Style.OLD);
+ d_renderer_center = new Gitg.DiffViewFileRendererText(info, handle_selection,
DiffViewFileRendererText.Style.ONE);
+ d_renderer_right = new Gitg.DiffViewFileRendererText(info, handle_selection,
DiffViewFileRendererText.Style.NEW);
+ d_scroll_left.add(d_renderer_left);
+ d_scroll_center.add(d_renderer_center);
+ d_scroll_right.add(d_renderer_right);
+ }
+
+ construct
+ {
+ }
+
+ public void add_hunk(Ggit.DiffHunk hunk, Gee.ArrayList<Ggit.DiffLine> lines)
+ {
+ can_select = false;
+ d_renderer_left.add_hunk(hunk, lines);
+ d_renderer_center.add_hunk(hunk, lines);
+ d_renderer_right.add_hunk(hunk, lines);
+ }
+
+ public bool has_selection
+ {
+ get
+ {
+ //return d_renderer_left.has_selection() || d_renderer_right.has_selection() ||
d_renderer_center.has_selection();
+ return false;
+ }
+ }
+
+ public bool can_select { get; construct set; }
+
+ public PatchSet selection
+ {
+ owned get
+ {
+ /*if (d_renderer_left.has_selection())
+ return d_renderer_left.get_selection();
+ if (d_renderer_center.has_selection())
+ return d_renderer_center.get_selection();
+ if (d_renderer_right.has_selection())
+ return d_renderer_right.get_selection();
+ */
+ return new PatchSet();
+ }
+ }
+}
diff --git a/libgitg/gitg-diff-view-file-renderer-text.vala b/libgitg/gitg-diff-view-file-renderer-text.vala
index 6ef2a984..b20dba7a 100644
--- a/libgitg/gitg-diff-view-file-renderer-text.vala
+++ b/libgitg/gitg-diff-view-file-renderer-text.vala
@@ -18,7 +18,7 @@
*/
[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-diff-view-file-renderer-text.ui")]
-class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFileRenderer
+class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFileRenderer,
DiffViewFileRendererTextable
{
private enum RegionType
{
@@ -27,6 +27,13 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
CONTEXT
}
+ public enum Style
+ {
+ ONE,
+ OLD,
+ NEW
+ }
+
private struct Region
{
public RegionType type;
@@ -61,6 +68,7 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
private Settings? d_stylesettings;
private FontManager d_font_manager;
+ public Style d_style { get; construct set; }
public bool new_is_workdir { get; construct set; }
@@ -170,29 +178,58 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
}
}
- public DiffViewFileRendererText(DiffViewFileInfo info, bool can_select)
+ public DiffViewFileRendererText(DiffViewFileInfo info, bool can_select, Style style)
{
- Object(info: info, can_select: can_select);
+ Object(info: info, can_select: can_select, d_style: style);
}
construct
{
var gutter = this.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);
+ if (d_style == Style.ONE)
+ {
+ 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);
+ 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;
+ 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);
+ gutter.insert(d_old_lines, 0);
+ gutter.insert(d_new_lines, 1);
+ gutter.insert(d_sym_lines, 2);
+ }
+ else if (d_style == Style.OLD)
+ {
+ d_old_lines = new DiffViewLinesRenderer(DiffViewLinesRenderer.Style.OLD);
+ d_sym_lines = new DiffViewLinesRenderer(DiffViewLinesRenderer.Style.SYMBOL_OLD);
+
+ this.bind_property("maxlines", d_old_lines, "maxlines", BindingFlags.DEFAULT |
BindingFlags.SYNC_CREATE);
+
+ d_old_lines.xpad = 8;
+ d_sym_lines.xpad = 6;
+
+ gutter.insert(d_old_lines, 0);
+ gutter.insert(d_sym_lines, 1);
+ }
+ else if (d_style == Style.NEW)
+ {
+ d_new_lines = new DiffViewLinesRenderer(DiffViewLinesRenderer.Style.NEW);
+ d_sym_lines = new DiffViewLinesRenderer(DiffViewLinesRenderer.Style.SYMBOL_NEW);
+
+ this.bind_property("maxlines", d_new_lines, "maxlines", BindingFlags.DEFAULT |
BindingFlags.SYNC_CREATE);
+
+ d_new_lines.xpad = 8;
+ d_sym_lines.xpad = 6;
+
+ gutter.insert(d_new_lines, 0);
+ gutter.insert(d_sym_lines, 1);
+ }
this.set_border_window_size(Gtk.TextWindowType.TOP, 1);
@@ -563,15 +600,35 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
var ctx = this.get_style_context();
- var old_lines_width = d_old_lines.size + d_old_lines.xpad * 2;
- var new_lines_width = d_new_lines.size + d_new_lines.xpad * 2;
+ var old_lines_width = 0;
+ var new_lines_width = 0;
+
+ switch (d_style)
+ {
+ case Style.ONE:
+ old_lines_width = d_old_lines.size + d_old_lines.xpad * 2;
+ new_lines_width = d_new_lines.size + d_new_lines.xpad * 2;
+ break;
+
+ case Style.OLD:
+ old_lines_width = d_old_lines.size + d_old_lines.xpad * 2;
+ break;
+
+ case Style.NEW:
+ new_lines_width = d_new_lines.size + d_new_lines.xpad * 2;
+ break;
+ }
+
var sym_lines_width = d_sym_lines.size + d_sym_lines.xpad * 2;
- ctx.save();
- Gtk.cairo_transform_to_window(cr, this, win);
- ctx.add_class("diff-lines-separator");
- ctx.render_frame(cr, 0, 0, old_lines_width, win.get_height());
- ctx.restore();
+ if (d_style == Style.ONE)
+ {
+ ctx.save();
+ Gtk.cairo_transform_to_window(cr, this, win);
+ ctx.add_class("diff-lines-separator");
+ ctx.render_frame(cr, 0, 0, old_lines_width, win.get_height());
+ ctx.restore();
+ }
ctx.save();
Gtk.cairo_transform_to_window(cr, this, win);
@@ -647,8 +704,7 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
int buffer_line = iter.get_line();
- /* Diff Content */
- var content = new StringBuilder();
+ int line_hunk_start = iter.get_line();
var region = Region() {
type = RegionType.CONTEXT,
@@ -659,6 +715,9 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
this.freeze_notify();
+ var add_line_num = 0;
+ var remove_line_num = 0;
+ var in_change_line = false;
for (var i = 0; i < lines.size; i++)
{
var line = lines[i];
@@ -716,7 +775,8 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
};
}
- region.length++;
+ if (d_style == Style.ONE)
+ region.length++;
if (added || removed)
{
@@ -748,45 +808,123 @@ class Gitg.DiffViewFileRendererText : Gtk.SourceView, DiffSelectable, DiffViewFi
text = text.slice(0, text.length - 1);
}
- content.append(text);
- buffer_line++;
- }
+ if (rtype == RegionType.CONTEXT)
+ {
+ if (d_style == Style.OLD || d_style == Style.NEW)
+ {
+ if (in_change_line == true)
+ {
+ bool check = d_style == Style.OLD ? add_line_num >
remove_line_num : remove_line_num > add_line_num;
+ if (check)
+ {
+ int end = d_style == Style.OLD ? add_line_num -
remove_line_num : remove_line_num - add_line_num;
+ for (var l = 0; l < end; l++)
+ {
+ Gtk.TextIter t_iter;
+ buffer.get_end_iter(out t_iter);
+ buffer.create_source_mark(null, "empty",
t_iter);
+
+ buffer.insert(ref iter, "\n", -1);
+ buffer_line++;
+ region.buffer_line_start = buffer_line;
+ }
+ }
+
+ add_line_num = 0;
+ remove_line_num = 0;
+ }
+
+ in_change_line = false;
+ }
- if (lines.size != 0)
- {
- d_regions += region;
- }
+ buffer.insert(ref iter, text, -1);
+ buffer_line++;
+ if (d_style == Style.OLD || d_style == Style.NEW)
+ {
+ region.length++;
+ }
+ }
- int line_hunk_start = iter.get_line();
+ RegionType? rtype_check = null;
+ string mark = null;
+ switch (d_style)
+ {
+ case Style.ONE:
+ case Style.OLD:
+ rtype_check = RegionType.REMOVED;
+ mark = "removed";
+ break;
+ case Style.NEW:
+ rtype_check = RegionType.ADDED;
+ mark = "added";
+ break;
+ }
- buffer.insert(ref iter, (string)content.data, -1);
+ if (rtype == rtype_check)
+ {
+ Gtk.TextIter t_iter;
+ buffer.get_end_iter(out t_iter);
+ buffer.create_source_mark(null, mark, t_iter);
- d_old_lines.add_hunk(line_hunk_start, iter.get_line(), hunk, lines);
- d_new_lines.add_hunk(line_hunk_start, iter.get_line(), hunk, lines);
- d_sym_lines.add_hunk(line_hunk_start, iter.get_line(), hunk, lines);
+ buffer.insert(ref iter, text, -1);
+ buffer_line++;
+ if (d_style == Style.OLD || d_style == Style.NEW)
+ {
+ region.length++;
- for (var i = 0; i < lines.size; i++)
- {
- var line = lines[i];
- string? category = null;
+ if (d_style == Style.OLD)
+ remove_line_num++;
+ else
+ add_line_num++;
+ in_change_line = true;
+ }
+ }
- switch (line.get_origin())
+ switch (d_style)
{
- case Ggit.DiffLineType.ADDITION:
- category = "added";
- break;
- case Ggit.DiffLineType.DELETION:
- category = "removed";
- break;
+ case Style.ONE:
+ case Style.OLD:
+ rtype_check = RegionType.ADDED;
+ break;
+ case Style.NEW:
+ rtype_check = RegionType.REMOVED;
+ break;
}
-
- if (category != null)
+ if (rtype == rtype_check)
{
- buffer.get_iter_at_line(out iter, line_hunk_start + i);
- buffer.create_source_mark(null, category, iter);
+ if (d_style == Style.OLD || d_style == Style.NEW)
+ {
+ if (d_style == Style.OLD)
+ add_line_num++;
+ else
+ remove_line_num++;
+ in_change_line = true;
+ } else if (d_style == Style.ONE) {
+ Gtk.TextIter t_iter;
+ buffer.get_end_iter(out t_iter);
+ buffer.create_source_mark(null, "added", t_iter);
+
+ buffer.insert(ref iter, text, -1);
+ buffer_line++;
+ }
}
}
+ if (lines.size != 0)
+ {
+ d_regions += region;
+ }
+
+ if (d_style == Style.ONE || d_style == Style.OLD)
+ {
+ d_old_lines.add_hunk(line_hunk_start, iter.get_line(), hunk, buffer);
+ }
+ if (d_style == Style.ONE || d_style == Style.NEW)
+ {
+ d_new_lines.add_hunk(line_hunk_start, iter.get_line(), hunk, buffer);
+ }
+ d_sym_lines.add_hunk(line_hunk_start, iter.get_line(), hunk, buffer);
+
this.thaw_notify();
sensitive = true;
diff --git a/libgitg/gitg-diff-view-file-renderer-textable.vala
b/libgitg/gitg-diff-view-file-renderer-textable.vala
new file mode 100644
index 00000000..0bf7e603
--- /dev/null
+++ b/libgitg/gitg-diff-view-file-renderer-textable.vala
@@ -0,0 +1,28 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2016 - Jesse van den Kieboom
+ *
+ * gitg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gitg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+interface Gitg.DiffViewFileRendererTextable : DiffSelectable, DiffViewFileRenderer
+{
+ public abstract bool wrap_lines { get; set; }
+ public abstract new int tab_width { get; set; }
+ public abstract int maxlines { get; set; }
+ public abstract bool highlight { get; construct set; }
+}
+
+// ex:ts=4 noet
diff --git a/libgitg/gitg-diff-view-file.vala b/libgitg/gitg-diff-view-file.vala
index 3794f92d..b7b9331e 100644
--- a/libgitg/gitg-diff-view-file.vala
+++ b/libgitg/gitg-diff-view-file.vala
@@ -40,7 +40,7 @@ class Gitg.DiffViewFile : Gtk.Grid
private bool d_expanded;
- public DiffViewFileRendererText? renderer_text {get; private set;}
+ public Gee.ArrayList<DiffViewFileRenderer> renderer_list {get; private set;}
public bool new_is_workdir { get; construct set; }
@@ -75,11 +75,44 @@ class Gitg.DiffViewFile : Gtk.Grid
public DiffViewFileInfo? info {get; construct set;}
private Gee.HashMap<Gtk.Widget, bool> d_diff_stat_visible_map = new Gee.HashMap<Gtk.Widget, bool>();
+ public bool has_selection()
+ {
+ bool has_selection = false;
+ foreach (DiffViewFileRenderer renderer in renderer_list)
+ {
+ var selectable = renderer as DiffSelectable;
+ if (selectable != null)
+ has_selection = selectable.has_selection;
+ if (has_selection)
+ break;
+ }
+ return has_selection;
+ }
+
+ public PatchSet get_selection()
+ {
+ var ret = new PatchSet();
+
+ foreach (var renderer in renderer_list)
+ {
+ var sel = renderer as DiffSelectable;
+
+ if (sel != null && sel.has_selection && sel.selection.patches.length != 0)
+ {
+ ret = sel.selection;
+ break;
+ }
+ }
+
+ return ret;
+ }
+
public DiffViewFile(DiffViewFileInfo? info)
{
Object(info: info);
bind_property("vexpand", d_stack_file_renderer, "vexpand", BindingFlags.SYNC_CREATE);
d_stack_file_renderer.notify["visible-child"].connect(page_changed);
+ renderer_list = new Gee.ArrayList<DiffViewFileRenderer>();
}
private void page_changed()
@@ -89,40 +122,53 @@ class Gitg.DiffViewFile : Gtk.Grid
d_diff_stat_file.set_visible(visible);
}
- public void add_renderer(Gtk.Widget widget, string name, string title, bool show_stats)
+ public void add_renderer(DiffViewFileRenderer renderer, Gtk.Widget widget, string name, string title,
bool show_stats)
{
d_diff_stat_visible_map.set(widget, show_stats);
+ renderer_list.add(renderer);
d_stack_file_renderer.add_titled(widget, name, title);
bool visible = d_stack_file_renderer.get_children().length() > 1;
d_stack_switcher.set_visible(visible);
}
- public void add_text_renderer(bool handle_selection)
+ public void add_text_renderer(bool handle_selection, uint num_parents)
{
- renderer_text = new DiffViewFileRendererText(info, handle_selection);
- renderer_text.show();
+ var renderer = new DiffViewFileRendererText(info, handle_selection,
DiffViewFileRendererText.Style.ONE);
+ renderer.show();
var scrolled_window = new Gtk.ScrolledWindow (null, null);
- scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
- scrolled_window.add(renderer_text);
+ scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER);
+ scrolled_window.add(renderer);
scrolled_window.show();
- renderer_text.bind_property("added", d_diff_stat_file, "added");
- renderer_text.bind_property("removed", d_diff_stat_file, "removed");
- add_renderer(scrolled_window, "text", _("Text"), true);
+ renderer.bind_property("added", d_diff_stat_file, "added");
+ renderer.bind_property("removed", d_diff_stat_file, "removed");
+ add_renderer(renderer, scrolled_window, "text", _("Unif"), true);
+
+ var renderer_split = new DiffViewFileRendererTextSplit(info, handle_selection);
+ renderer_split.show();
+ add_renderer(renderer_split, renderer_split, "splittext", _("Split"), true);
+
+ if (num_parents > 1)
+ {
+ var renderer_three = new DiffViewFileRendererTextThree(info, handle_selection);
+ renderer_three.show();
+ add_renderer(renderer_three, renderer_three, "threetext", _("Merge"), true);
+ }
+
}
public void add_binary_renderer()
{
var renderer = new DiffViewFileRendererBinary();
renderer.show();
- add_renderer(renderer, "binary", _("Binary"), false);
+ add_renderer(renderer, renderer, "binary", _("Binary"), false);
}
public void add_image_renderer()
{
var renderer = new DiffViewFileRendererImage(info.repository, info.delta);
renderer.show();
- add_renderer(renderer, "image", _("Image"), false);
+ add_renderer(renderer, renderer, "image", _("Image"), false);
}
protected override void constructed()
@@ -253,16 +299,9 @@ class Gitg.DiffViewFile : Gtk.Grid
public void add_hunk(Ggit.DiffHunk hunk, Gee.ArrayList<Ggit.DiffLine> lines)
{
- if (renderer_text != null) {
- renderer_text.add_hunk(hunk, lines);
- }
- foreach (Gtk.Widget page in d_stack_file_renderer.get_children())
+ foreach (DiffViewFileRenderer renderer in renderer_list)
{
- if (page is DiffViewFileRenderer)
- {
- var renderer = (DiffViewFileRenderer)page;
- renderer.add_hunk(hunk, lines);
- }
+ renderer.add_hunk(hunk, lines);
}
}
}
diff --git a/libgitg/gitg-diff-view-lines-renderer.vala b/libgitg/gitg-diff-view-lines-renderer.vala
index 51d8444a..51d50f0e 100644
--- a/libgitg/gitg-diff-view-lines-renderer.vala
+++ b/libgitg/gitg-diff-view-lines-renderer.vala
@@ -23,7 +23,17 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
{
OLD,
NEW,
- SYMBOL
+ SYMBOL,
+ SYMBOL_OLD,
+ SYMBOL_NEW
+ }
+
+ private enum Line_Style
+ {
+ CONTEXT,
+ ADDED,
+ REMOVED,
+ EMPTY
}
private int d_num_digits;
@@ -104,7 +114,7 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
if (info == null || (line - info.start) >= info.line_infos.length)
{
- if (is_hunk && style != Style.SYMBOL)
+ if (is_hunk && style != Style.SYMBOL && style != Style.SYMBOL_OLD && style !=
Style.SYMBOL_NEW)
{
set_text("...", -1);
}
@@ -186,48 +196,87 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
d_num_digits_fill = string.nfill(num_digits, ' ');
}
- private string[] precalculate_line_strings(Ggit.DiffHunk hunk, Gee.ArrayList<Ggit.DiffLine> lines)
+ private Line_Style get_origin(int buffer_line, Gtk.SourceBuffer buffer)
+ {
+ var origin = Line_Style.CONTEXT;
+
+ var mark = buffer.get_source_marks_at_line(buffer_line, null);
+ if (mark != null)
+ {
+ mark.@foreach ((item) => {
+ switch (item.get_category())
+ {
+ case "added":
+ origin = Line_Style.ADDED;
+ break;
+ case "removed":
+ origin = Line_Style.REMOVED;
+ break;
+ case "empty":
+ origin = Line_Style.EMPTY;
+ break;
+ }
+ });
+ }
+
+ return origin;
+ }
+
+ private string[] precalculate_line_strings(Ggit.DiffHunk hunk, Gtk.SourceBuffer buffer, int
buffer_line_start)
{
var oldn = hunk.get_old_start();
var newn = hunk.get_new_start();
- var lns = lines;
+ Gtk.TextIter iter;
+ buffer.get_end_iter(out iter);
+ int buffer_line_end = iter.get_line();
- var line_infos = new string[lns.size];
+ var line_infos = new string[buffer_line_end - buffer_line_start + 1];
- for (var i = 0; i < lns.size; i++)
+ for (var i = 0; i <= (buffer_line_end - buffer_line_start); i++)
{
- var line = lns[i];
- var origin = line.get_origin();
+ var origin = get_origin(buffer_line_start + i, buffer);
string ltext = "";
switch (style)
{
case Style.NEW:
- if (origin == Ggit.DiffLineType.CONTEXT || origin ==
Ggit.DiffLineType.ADDITION)
+ if (origin == Line_Style.CONTEXT || origin == Line_Style.ADDED)
{
ltext = "%*d".printf(d_num_digits, newn);
newn++;
}
break;
case Style.OLD:
- if (origin == Ggit.DiffLineType.CONTEXT || origin ==
Ggit.DiffLineType.DELETION)
+ if (origin == Line_Style.CONTEXT || origin == Line_Style.REMOVED)
{
ltext = "%*d".printf(d_num_digits, oldn);
oldn++;
}
break;
case Style.SYMBOL:
- if (origin == Ggit.DiffLineType.ADDITION)
+ if (origin == Line_Style.ADDED)
{
ltext = "+";
}
- else if (origin == Ggit.DiffLineType.DELETION)
+ else if (origin == Line_Style.REMOVED)
+ {
+ ltext = "-";
+ }
+ break;
+ case Style.SYMBOL_OLD:
+ if (origin == Line_Style.REMOVED)
{
ltext = "-";
}
break;
+ case Style.SYMBOL_NEW:
+ if (origin == Line_Style.ADDED)
+ {
+ ltext = "+";
+ }
+ break;
}
line_infos[i] = ltext;
@@ -235,8 +284,7 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
return line_infos;
}
-
- public void add_hunk(int buffer_line_start, int buffer_line_end, Ggit.DiffHunk hunk,
Gee.ArrayList<Ggit.DiffLine> lines)
+ public void add_hunk(int buffer_line_start, int buffer_line_end, Ggit.DiffHunk hunk, Gtk.SourceBuffer
buffer)
{
HunkInfo info = HunkInfo();
@@ -246,7 +294,7 @@ class Gitg.DiffViewLinesRenderer : Gtk.SourceGutterRendererText
info.end = buffer_line_end;
info.hunk_line = buffer_line_start - 1;
info.hunk = hunk;
- info.line_infos = precalculate_line_strings(hunk, lines);
+ info.line_infos = precalculate_line_strings(hunk, buffer, buffer_line_start);
d_hunks_list.add(info);
diff --git a/libgitg/gitg-diff-view.vala b/libgitg/gitg-diff-view.vala
index 86c87f70..9e182fb1 100644
--- a/libgitg/gitg-diff-view.vala
+++ b/libgitg/gitg-diff-view.vala
@@ -590,7 +590,7 @@ public class Gitg.DiffView : Gtk.Grid
if (d_diff != null)
{
- update_diff(d_diff, preserve_expanded, d_cancellable);
+ update_diff(d_diff, preserve_expanded, d_cancellable, d_commit.get_parents().size);
}
}
@@ -645,9 +645,7 @@ public class Gitg.DiffView : Gtk.Grid
foreach (var file in d_grid_files.get_children())
{
- var selectable = ((Gitg.DiffViewFile) file).renderer_text as DiffSelectable;
-
- if (selectable != null && selectable.has_selection)
+ if (((Gitg.DiffViewFile) file).has_selection())
{
something_selected = true;
break;
@@ -695,7 +693,7 @@ public class Gitg.DiffView : Gtk.Grid
return "";
}
- private void update_diff(Ggit.Diff diff, bool preserve_expanded, Cancellable? cancellable)
+ private void update_diff(Ggit.Diff diff, bool preserve_expanded, Cancellable? cancellable, uint
num_parents)
{
var nqueries = 0;
var finished = false;
@@ -705,7 +703,7 @@ public class Gitg.DiffView : Gtk.Grid
if (nqueries == 0 && finished && (cancellable == null || !cancellable.is_cancelled()))
{
finished = false;
- update_diff_hunks(diff, preserve_expanded, infomap, cancellable);
+ update_diff_hunks(diff, preserve_expanded, infomap, cancellable, num_parents);
}
};
@@ -732,7 +730,7 @@ public class Gitg.DiffView : Gtk.Grid
check_finish();
}
- private void update_diff_hunks(Ggit.Diff diff, bool preserve_expanded, Gee.HashMap<string,
DiffViewFileInfo> infomap, Cancellable? cancellable)
+ private void update_diff_hunks(Ggit.Diff diff, bool preserve_expanded, Gee.HashMap<string,
DiffViewFileInfo> infomap, Cancellable? cancellable, uint num_parents)
{
var files = new Gee.ArrayList<Gitg.DiffViewFile>();
@@ -836,13 +834,20 @@ public class Gitg.DiffView : Gtk.Grid
}
if (can_diff_as_text)
{
- current_file.add_text_renderer(handle_selection);
- var renderer_text = current_file.renderer_text;
- bind_property("highlight", renderer_text, "highlight",
BindingFlags.SYNC_CREATE);
- bind_property("wrap-lines", renderer_text, "wrap-lines",
BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE);
- bind_property("tab-width", renderer_text, "tab-width",
BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE);
- renderer_text.maxlines = maxlines;
-
renderer_text.notify["has-selection"].connect(on_selection_changed);
+ current_file.add_text_renderer(handle_selection, num_parents);
+ var renderer_list = current_file.renderer_list;
+ foreach (DiffViewFileRenderer renderer in renderer_list)
+ {
+ var renderer_text = renderer as
DiffViewFileRendererTextable;
+ if (renderer_text != null)
+ {
+ bind_property("highlight", renderer_text,
"highlight", BindingFlags.SYNC_CREATE);
+ bind_property("wrap-lines", renderer_text,
"wrap-lines", BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE);
+ bind_property("tab-width", renderer_text,
"tab-width", BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE);
+ renderer_text.maxlines = maxlines;
+
renderer_text.notify["has-selection"].connect(on_selection_changed);
+ }
+ }
}
if (current_is_binary)
{
@@ -962,12 +967,7 @@ public class Gitg.DiffView : Gtk.Grid
foreach (var file in d_grid_files.get_children())
{
- var sel = ((Gitg.DiffViewFile) file).renderer_text as DiffSelectable;
-
- if (sel != null && sel.has_selection && sel.selection.patches.length != 0)
- {
- ret += sel.selection;
- }
+ ret += ((Gitg.DiffViewFile)file).get_selection();
}
return ret;
diff --git a/libgitg/meson.build b/libgitg/meson.build
index e20e07c8..56105239 100644
--- a/libgitg/meson.build
+++ b/libgitg/meson.build
@@ -43,6 +43,9 @@ sources = files(
'gitg-diff-view-file-renderer-binary.vala',
'gitg-diff-view-file-renderer-image.vala',
'gitg-diff-view-file-renderer-text.vala',
+ 'gitg-diff-view-file-renderer-textable.vala',
+ 'gitg-diff-view-file-renderer-text-split.vala',
+ 'gitg-diff-view-file-renderer-text-three.vala',
'gitg-diff-view-file-renderer.vala',
'gitg-diff-view-file-selectable.vala',
'gitg-diff-view-file.vala',
@@ -76,6 +79,8 @@ resource_data = files(
'resources/ui/gitg-diff-view-file-renderer-binary.ui',
'resources/ui/gitg-diff-view-file-renderer-image.ui',
'resources/ui/gitg-diff-view-file-renderer-text.ui',
+ 'resources/ui/gitg-diff-view-file-renderer-text-split.ui',
+ 'resources/ui/gitg-diff-view-file-renderer-text-three.ui',
'resources/ui/gitg-diff-view-file.ui',
'resources/ui/gitg-diff-view-options-spacing.ui',
'resources/ui/gitg-diff-view-options.ui',
diff --git a/libgitg/resources/resources.xml b/libgitg/resources/resources.xml
index b47a8e21..87a4f333 100644
--- a/libgitg/resources/resources.xml
+++ b/libgitg/resources/resources.xml
@@ -8,6 +8,8 @@
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-file-renderer-image.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-file-renderer-text.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-file-renderer-binary.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-file-renderer-text-split.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-file-renderer-text-three.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-options-spacing.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-diff-view-commit-details.ui</file>
diff --git a/libgitg/resources/ui/gitg-diff-view-file-renderer-text-split.ui
b/libgitg/resources/ui/gitg-diff-view-file-renderer-text-split.ui
new file mode 100644
index 00000000..572bb56f
--- /dev/null
+++ b/libgitg/resources/ui/gitg-diff-view-file-renderer-text-split.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.19.0 -->
+<interface>
+ <requires lib="gtk+" version="3.16"/>
+ <template class="GitgDiffViewFileRendererTextSplit" parent="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="homogeneous">False</property>
+ <property name="orientation">horizontal</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scroll_left">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="vscrollbar-policy">never</property>
+ </object>
+ <packing>
+ <property name="pack-type">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scroll_right">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="vscrollbar-policy">never</property>
+ </object>
+ <packing>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
+ </template>
+</interface>
diff --git a/libgitg/resources/ui/gitg-diff-view-file-renderer-text-three.ui
b/libgitg/resources/ui/gitg-diff-view-file-renderer-text-three.ui
new file mode 100644
index 00000000..a3f7772d
--- /dev/null
+++ b/libgitg/resources/ui/gitg-diff-view-file-renderer-text-three.ui
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.19.0 -->
+<interface>
+ <requires lib="gtk+" version="3.16"/>
+ <template class="GitgDiffViewFileRendererTextThree" parent="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="homogeneous">False</property>
+ <property name="orientation">horizontal</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scroll_left">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="vscrollbar-policy">never</property>
+ </object>
+ <packing>
+ <property name="pack-type">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scroll_center">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="vscrollbar-policy">never</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scroll_right">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="vscrollbar-policy">never</property>
+ </object>
+ <packing>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
+ </template>
+</interface>
diff --git a/libgitg/resources/ui/gitg-diff-view-file.ui b/libgitg/resources/ui/gitg-diff-view-file.ui
index 22e67905..8fcd9118 100644
--- a/libgitg/resources/ui/gitg-diff-view-file.ui
+++ b/libgitg/resources/ui/gitg-diff-view-file.ui
@@ -80,8 +80,6 @@
<child>
<object class="GtkStack" id="stack_file_renderer">
<property name="visible">True</property>
- <property name="vexpand">True</property>
- <property name="hexpand">True</property>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]