Commit 79ff5406 authored by Alberto Fanjul's avatar Alberto Fanjul
Browse files

Add direction on diff model

Allow diffbar to paint it correctly:

- LTR: old buffer is on left and new buffer is on right
- RTL: old buffer is on right and new buffer on left
parent 8aa99d53
Pipeline #93926 failed with stages
in 6 minutes and 12 seconds
......@@ -6,6 +6,11 @@ public class DiffModel: Object {
REMOVED
}
public enum Direction {
RTL,
LTR
}
public signal void removed ();
public int f0 { get; set; }
......@@ -13,4 +18,5 @@ public class DiffModel: Object {
public int t0 { get; set; }
public int t1 { get; set; }
public DiffType diff_type { get; set; }
public Direction direction { get; set; }
}
public class LinkMap:Gtk.DrawingArea {
public Gtk.SourceView left_sourceview { get; set; }
public Gtk.SourceView right_sourceview { get; set; }
public Gtk.SourceView left_sourceview { get; set; }
public Gtk.SourceView right_sourceview { get; set; }
private List<weak DiffModel> d_diff_model_list = null;
private List<weak DiffModel> d_diff_model_list = null;
public LinkMap () {
Object ();
public LinkMap () {
Object ();
reset ();
}
}
public void reset () {
d_diff_model_list.foreach((model) => {
......@@ -28,174 +28,184 @@ public class LinkMap:Gtk.DrawingArea {
});
}
public override bool draw (Cairo.Context context) {
if (d_diff_model_list != null && d_diff_model_list.length () > 0) {
Gtk.Allocation ? left_rectangle = null;
Gtk.Allocation ? right_rectangle = null;
left_sourceview.get_allocation (out left_rectangle);
right_sourceview.get_allocation (out right_rectangle);
//int[] pix_start = { left_rectangle.y, right_rectangle.y };
int dxl = 0, dyl = 0;
left_sourceview.translate_coordinates (get_toplevel (), 0, 0, out dxl, out dyl);
int dxr = 0, dyr = 0;
right_sourceview.translate_coordinates (get_toplevel (), 0, 0, out dxr, out dyr);
int[] y_offset = { dyl + 1, dyr + 1 };
var clip_y = array_get_min (y_offset) - 1;
int[] heights = { left_rectangle.height, right_rectangle.height };
var clip_height = array_get_max (heights) + 2;
Gtk.Allocation ? allocation = null;
get_allocation (out allocation);
weak Gtk.StyleContext style_context = get_style_context ();
style_context.render_background (context, 0, clip_y, allocation.width, clip_height);
context.set_line_width (1.0);
int height = get_allocated_height ();
/*
int[] visible = {
get_line_num_for_y (left_sourceview, pix_start[0]),
get_line_num_for_y (left_sourceview, pix_start[0] + height),
get_line_num_for_y (right_sourceview, pix_start[1]),
get_line_num_for_y (right_sourceview, pix_start[1] + height),
};
*/
int wtotal = get_allocated_width ();
// For bezier control points
double[] x_steps = { -0.5, wtotal / 2, wtotal / 2, wtotal + 0.5 };
double q_rad = GLib.Math.PI / 2;
// left, right = self.view_indices
var RADIUS = 3;
d_diff_model_list.foreach ((model) => {
int f0 = model.f0;
int t0 = model.t0;
int f1 = model.f1;
int t1 = model.t1;
f1 = f1 == f0 ? f1 : f1 - 1;
t1 = t1 == t0 ? t1 : t1 - 1;
if ((t0 < 0 && t1 < 0) || (t0 > height && t1 > height)) {
if (f0 == f1)
return;
context.arc (x_steps[0], f0 - 0.5 + RADIUS, RADIUS, -q_rad, 0);
context.arc (x_steps[0], f1 - 0.5 - RADIUS, RADIUS, 0, q_rad);
context.close_path ();
} else if ((f0 < 0 && f1 < 0) || (f0 > height && f1 > height)) {
if (t0 == t1)
return;
context.arc_negative (x_steps[3], t0 - 0.5 + RADIUS, RADIUS,-q_rad, q_rad * 2);
context.arc_negative (x_steps[3], t1 - 0.5 - RADIUS, RADIUS,q_rad * 2, q_rad);
context.close_path ();
} else {
context.move_to (x_steps[0], f0 - 0.5);
context.curve_to (x_steps[1], f0 - 0.5,x_steps[2], t0 - 0.5,x_steps[3], t0 - 0.5);
context.line_to (x_steps[3], t1 - 0.5);
context.curve_to (x_steps[2], t1 - 0.5,x_steps[1], f1 - 0.5,x_steps[0], f1 - 0.5);
context.close_path ();
}
// context.set_source_rgba(self.fill_colors[c[0]]);
var color = Gdk.RGBA ();
string color_str = null;
switch (model.diff_type) {
case DiffModel.DiffType.ADD:
color_str = "#008800";
break;
case DiffModel.DiffType.MODIFIED:
color_str = "#1d59d6";
break;
case DiffModel.DiffType.REMOVED:
color_str = "#ff0000";
break;
}
color.parse (color_str);
context.set_source_rgba (color.red, color.green, color.blue, color.alpha);
context.fill_preserve ();
// var chunk_idx = self.filediff.linediffer.locate_chunk(left, c[1])[0]
// if chunk_idx == self.filediff.cursor.chunk:
//if (false) {
// // var highlight = self.fill_colors['current-chunk-highlight']
// context.set_source_rgba ( /*highlight*/ 0, 0, 0, 0);
// context.fill_preserve ();
//}
// context.set_source_rgba(self.line_colors[c[0]]);
color_str = null;
switch (model.diff_type) {
case DiffModel.DiffType.ADD:
color_str = "#a5ff4c";
break;
case DiffModel.DiffType.MODIFIED:
color_str = "#0053a6";
break;
case DiffModel.DiffType.REMOVED:
color_str = "#ac3b39";
break;
}
color.parse(color_str);
context.set_source_rgba (color.red, color.green, color.blue, color.alpha);
context.stroke ();
});
return true;
}
return false;
}
public override bool draw (Cairo.Context context) {
if (d_diff_model_list != null && d_diff_model_list.length () > 0) {
Gtk.Allocation ? left_rectangle = null;
Gtk.Allocation ? right_rectangle = null;
left_sourceview.get_allocation (out left_rectangle);
right_sourceview.get_allocation (out right_rectangle);
//int[] pix_start = { left_rectangle.y, right_rectangle.y };
int dxl = 0, dyl = 0;
left_sourceview.translate_coordinates (get_toplevel (), 0, 0, out dxl, out dyl);
int dxr = 0, dyr = 0;
right_sourceview.translate_coordinates (get_toplevel (), 0, 0, out dxr, out dyr);
int[] y_offset = { dyl + 1, dyr + 1 };
var clip_y = array_get_min (y_offset) - 1;
int[] heights = { left_rectangle.height, right_rectangle.height };
var clip_height = array_get_max (heights) + 2;
Gtk.Allocation ? allocation = null;
get_allocation (out allocation);
weak Gtk.StyleContext style_context = get_style_context ();
style_context.render_background (context, 0, clip_y, allocation.width, clip_height);
context.set_line_width (1.0);
int height = get_allocated_height ();
/*
int[] visible = {
get_line_num_for_y (left_sourceview, pix_start[0]),
get_line_num_for_y (left_sourceview, pix_start[0] + height),
get_line_num_for_y (right_sourceview, pix_start[1]),
get_line_num_for_y (right_sourceview, pix_start[1] + height),
};
*/
int wtotal = get_allocated_width ();
// For bezier control points
double[] x_steps = { -0.5, wtotal / 2, wtotal / 2, wtotal + 0.5 };
double q_rad = GLib.Math.PI / 2;
// left, right = self.view_indices
var RADIUS = 3;
d_diff_model_list.foreach ((model) => {
int f0, t0, f1, t1;
if (model.direction == DiffModel.Direction.RTL) {
f0 = model.f0;
f1 = model.f1;
t0 = model.t0;
t1 = model.t1;
} else {
f0 = model.t0;
f1 = model.t1;
t0 = model.f0;
t1 = model.f1;
}
f1 = f1 == f0 ? f1 : f1 - 1;
t1 = t1 == t0 ? t1 : t1 - 1;
if ((t0 < 0 && t1 < 0) || (t0 > height && t1 > height)) {
if (f0 == f1)
return;
context.arc (x_steps[0], f0 - 0.5 + RADIUS, RADIUS, -q_rad, 0);
context.arc (x_steps[0], f1 - 0.5 - RADIUS, RADIUS, 0, q_rad);
context.close_path ();
} else if ((f0 < 0 && f1 < 0) || (f0 > height && f1 > height)) {
if (t0 == t1)
return;
context.arc_negative (x_steps[3], t0 - 0.5 + RADIUS, RADIUS,-q_rad, q_rad * 2);
context.arc_negative (x_steps[3], t1 - 0.5 - RADIUS, RADIUS,q_rad * 2, q_rad);
context.close_path ();
} else {
context.move_to (x_steps[0], f0 - 0.5);
context.curve_to (x_steps[1], f0 - 0.5,x_steps[2], t0 - 0.5,x_steps[3], t0 - 0.5);
context.line_to (x_steps[3], t1 - 0.5);
context.curve_to (x_steps[2], t1 - 0.5,x_steps[1], f1 - 0.5,x_steps[0], f1 - 0.5);
context.close_path ();
}
// context.set_source_rgba(self.fill_colors[c[0]]);
var color = Gdk.RGBA ();
string color_str = null;
switch (model.diff_type) {
case DiffModel.DiffType.ADD:
color_str = "#008800";
break;
case DiffModel.DiffType.MODIFIED:
color_str = "#1d59d6";
break;
case DiffModel.DiffType.REMOVED:
color_str = "#ff0000";
break;
}
color.parse (color_str);
context.set_source_rgba (color.red, color.green, color.blue, color.alpha);
context.fill_preserve ();
// var chunk_idx = self.filediff.linediffer.locate_chunk(left, c[1])[0]
// if chunk_idx == self.filediff.cursor.chunk:
//if (false) {
// // var highlight = self.fill_colors['current-chunk-highlight']
// context.set_source_rgba ( /*highlight*/ 0, 0, 0, 0);
// context.fill_preserve ();
//}
// context.set_source_rgba(self.line_colors[c[0]]);
color_str = null;
switch (model.diff_type) {
case DiffModel.DiffType.ADD:
color_str = "#a5ff4c";
break;
case DiffModel.DiffType.MODIFIED:
color_str = "#0053a6";
break;
case DiffModel.DiffType.REMOVED:
color_str = "#ac3b39";
break;
}
color.parse(color_str);
context.set_source_rgba (color.red, color.green, color.blue, color.alpha);
context.stroke ();
});
return true;
}
return false;
}
/*
int view_offset_line (Gtk.SourceView source_view, int line_num, int pix_start, int y_offset) {
int line_start = get_y_for_line_num (source_view, line_num);
return line_start - pix_start + y_offset;
}
int get_y_for_line_num (Gtk.SourceView source_view, int line) {
var buf = source_view.get_buffer ();
Gtk.TextIter it;
buf.get_iter_at_line (out it, line);
int y, h;
source_view.get_line_yrange (it, out y, out h);
if (line >= buf.get_line_count ())
return y + h;
return y;
}
int get_line_num_for_y (Gtk.SourceView source_view, int y) {
int line_start;
source_view.get_line_at_y (null, y, out line_start);
return line_start;
}
int view_offset_line (Gtk.SourceView source_view, int line_num, int pix_start, int y_offset) {
int line_start = get_y_for_line_num (source_view, line_num);
return line_start - pix_start + y_offset;
}
int get_y_for_line_num (Gtk.SourceView source_view, int line) {
var buf = source_view.get_buffer ();
Gtk.TextIter it;
buf.get_iter_at_line (out it, line);
int y, h;
source_view.get_line_yrange (it, out y, out h);
if (line >= buf.get_line_count ())
return y + h;
return y;
}
int get_line_num_for_y (Gtk.SourceView source_view, int y) {
int line_start;
source_view.get_line_at_y (null, y, out line_start);
return line_start;
}
*/
int array_get_max (int[] array) {
int max = array[0];
for (int i = 0; i < array.length; i++)
if (array[i] > max)
max = array[i];
return max;
}
int array_get_min (int[] array) {
int min = array[0];
for (int i = 0; i < array.length; i++)
if (array[i] < min)
min = array[i];
return min;
}
int array_get_max (int[] array) {
int max = array[0];
for (int i = 0; i < array.length; i++)
if (array[i] > max)
max = array[i];
return max;
}
int array_get_min (int[] array) {
int min = array[0];
for (int i = 0; i < array.length; i++)
if (array[i] < min)
min = array[i];
return min;
}
}
......@@ -19,55 +19,55 @@
[GtkTemplate (ui = "/org/gnome/Diferencia/window.ui")]
public class Window : Gtk.ApplicationWindow {
[GtkChild (name = "left_sourceview")]
private Gtk.SourceView left_sourceview;
[GtkChild (name = "left_sourceview")]
private Gtk.SourceView left_sourceview;
[GtkChild (name = "mid_sourceview")]
private Gtk.SourceView mid_sourceview;
[GtkChild (name = "mid_sourceview")]
private Gtk.SourceView mid_sourceview;
[GtkChild (name = "right_sourceview")]
private Gtk.SourceView right_sourceview;
[GtkChild (name = "right_sourceview")]
private Gtk.SourceView right_sourceview;
[GtkChild (name = "left_linkmap")]
private LinkMap left_linkmap;
[GtkChild (name = "left_linkmap")]
private LinkMap left_linkmap;
[GtkChild (name = "right_linkmap")]
private LinkMap right_linkmap;
[GtkChild (name = "right_linkmap")]
private LinkMap right_linkmap;
[GtkChild (name = "three_way")]
private Gtk.Switch three_way;
[GtkChild (name = "three_way")]
private Gtk.Switch three_way;
[GtkChild (name = "left_diffmodel_list_ui")]
private Gtk.ListBox left_diffmodel_list_ui;
[GtkChild (name = "left_diffmodel_list_ui")]
private Gtk.ListBox left_diffmodel_list_ui;
[GtkChild (name = "right_ui_box")]
private Gtk.Box right_ui_box;
[GtkChild (name = "right_ui_box")]
private Gtk.Box right_ui_box;
[GtkChild (name = "right_diffmodel_list_ui")]
private Gtk.ListBox right_diffmodel_list_ui;
[GtkChild (name = "right_diffmodel_list_ui")]
private Gtk.ListBox right_diffmodel_list_ui;
[GtkChild (name = "list_box")]
private Gtk.Box listbox;
[GtkChild (name = "list_box")]
private Gtk.Box listbox;
[GtkChild (name = "diff_box")]
private Gtk.Box diff_box;
[GtkChild (name = "diff_box")]
private Gtk.Box diff_box;
[GtkChild (name = "right_scrolledwindow")]
private Gtk.ScrolledWindow right_scrolledwindow;
[GtkChild (name = "right_scrolledwindow")]
private Gtk.ScrolledWindow right_scrolledwindow;
string file1_path = "a";
string file2_path = "b";
string file3_path = "c";
public Window (Gtk.Application app, File[] files) {
Object (application: app);
if (files.length < 3)
{
hide_three_way ();
three_way.active = false;
public Window (Gtk.Application app, File[] files) {
Object (application: app);
if (files.length < 3)
{
hide_three_way ();
three_way.active = false;
}
load_files.begin (files, (obj, res) => {
load_files.begin (files, (obj, res) => {
compare_all_buffers ();
load_files.end(res);
});
......@@ -118,20 +118,20 @@ public class Window : Gtk.ApplicationWindow {
stdout.printf ("Error: %s\n", e.message);
}
right_sourceview.buffer.changed.connect (() => {
right_sourceview.buffer.changed.connect (() => {
compare_right_to_mid_buffer ();
});
left_sourceview.buffer.changed.connect (() => {
left_sourceview.buffer.changed.connect (() => {
compare_left_to_mid_buffer ();
});
mid_sourceview.buffer.changed.connect (() => {
mid_sourceview.buffer.changed.connect (() => {
compare_all_buffers ();
});
left_linkmap.left_sourceview = left_sourceview;
left_linkmap.right_sourceview = mid_sourceview;
right_linkmap.left_sourceview = mid_sourceview;
right_linkmap.right_sourceview = right_sourceview;
left_linkmap.left_sourceview = left_sourceview;
left_linkmap.right_sourceview = mid_sourceview;
right_linkmap.left_sourceview = mid_sourceview;
right_linkmap.right_sourceview = right_sourceview;
}
private void compare_all_buffers () {
......@@ -140,18 +140,16 @@ public class Window : Gtk.ApplicationWindow {
}
private void compare_right_to_mid_buffer () {
//TODO: We need to paint linkmap in reverse direction for right to mid
compare_buffers (right_linkmap, right_sourceview, mid_sourceview, right_diffmodel_list_ui);
compare_buffers (right_linkmap, right_sourceview, mid_sourceview, right_diffmodel_list_ui, DiffModel.Direction.LTR);
}
private void compare_left_to_mid_buffer () {
compare_buffers (left_linkmap, left_sourceview, mid_sourceview, left_diffmodel_list_ui);
compare_buffers (left_linkmap, left_sourceview, mid_sourceview, left_diffmodel_list_ui, DiffModel.Direction.RTL);
}
private void compare_buffers (LinkMap linkmap, Gtk.SourceView old_sourceview,
Gtk.SourceView new_sourceview, Gtk.ListBox diffmodel_list_ui) {
try
{
private void compare_buffers (LinkMap linkmap, Gtk.SourceView old_sourceview, Gtk.SourceView new_sourceview,
Gtk.ListBox diffmodel_list_ui, DiffModel.Direction direction) {
try {
DiffModel diffmodel = null;
linkmap.reset();
int new_linepos = 0;
......@@ -162,35 +160,35 @@ public class Window : Gtk.ApplicationWindow {
if (!old_text.has_suffix("\n")) {
old_text = old_text.concat("\n");
}
var new_text = new_sourceview.buffer.text;
var new_text = new_sourceview.buffer.text;
if (!new_text.has_suffix("\n")) {
new_text = new_text.concat("\n");
}
int old_linecount = old_sourceview.buffer.get_line_count ();
int new_linecount = new_sourceview.buffer.get_line_count ();
var diff = new Ggit.Diff.buffers(old_text.data, file1_path,
var diff = new Ggit.Diff.buffers(old_text.data, file1_path,
new_text.data, file2_path, null);
diff.foreach(
(delta, progress) => {
diff.foreach(
(delta, progress) => {
print ("delta:\n");
print ("- old file %s\n", delta.get_old_file().get_path());
print ("- new file %s\n", delta.get_new_file().get_path());
return 0;
},
(delta, binary) => {
return 0;
},
(delta, binary) => {
print ("binary\n");
return 0;
},
(delta, hunk) => {
return 0;
},
(delta, hunk) => {
print ("hunk:\n");
print ("- old start: %d lines %d\n", hunk.get_old_start (), hunk.get_old_lines ());
print ("- new start: %d lines %d\n", hunk.get_new_start (), hunk.get_new_lines ());
old_linepos = hunk.get_old_start ();
new_linepos = hunk.get_new_start ();
print ("old_linepos: %d, new_linepos: %d\n", old_linepos, new_linepos);
return 0;
},
(delta, hunk, line) => {
return 0;
},
(delta, hunk, line) => {
int old_lineno = line.get_old_lineno ();
int new_lineno = line.get_new_lineno ();
old_linepos += old_lineno;
......@@ -204,10 +202,10 @@ public class Window : Gtk.ApplicationWindow {
print ("- text: %s\n", line.get_text ());
print ("old_linepos: %d, new_linepos: %d\n", old_linepos, new_linepos);
if (origin == Ggit.DiffLineType.ADDITION || origin == Ggit.DiffLineType.DELETION) {
diffmodel = add_diffmodel (linkmap, diffmodel_list_ui);
if (origin == Ggit.DiffLineType.ADDITION || origin == Ggit.DiffLineType.DELETION) {
diffmodel = add_diffmodel (linkmap, diffmodel_list_ui, direction);
if (origin == Ggit.DiffLineType.ADDITION) {
if (origin == Ggit.DiffLineType.ADDITION) {
diffmodel.diff_type = DiffModel.DiffType.ADD;
old_lineno = old_linepos + 1;
......@@ -278,62 +276,63 @@ public class Window : Gtk.ApplicationWindow {
print ("add model f(%d,%d) -> t(%d,%d) = %s\n",
diffmodel.f0, diffmodel.f1, diffmodel.t0, diffmodel.t1, diffmodel.diff_type.to_string());
}
return 0;
}
);
} catch (Error e) {
return 0;
}
);
} catch (Error e) {
print("error: %s\n", e.message);
}
}
}
public DiffModel add_diffmodel (LinkMap linkmap, Gtk.ListBox diffmodel_list_ui) {
DiffModelUI ui = new DiffModelUI ();
public DiffModel add_diffmodel (LinkMap linkmap, Gtk.ListBox diffmodel_list_ui, DiffModel.Direction direction) {
DiffModelUI ui = new DiffModelUI ();