diff --git a/gitg/gitg-dash-view.vala b/gitg/gitg-dash-view.vala index deab2539..88a483fb 100644 --- a/gitg/gitg-dash-view.vala +++ b/gitg/gitg-dash-view.vala @@ -127,6 +127,22 @@ class DashView : Gtk.Grid, GitgExt.UIElement, GitgExt.Activity, GitgExt.Selectab owned get { return null; } } + private string d_search_path; + + public string search_path + { + owned get { return d_search_path; } + + set + { + if (d_search_path != value) + { + d_search_path = value; + update_search_path(); + } + } + } + private string d_search_text; public string search_text @@ -150,6 +166,10 @@ class DashView : Gtk.Grid, GitgExt.UIElement, GitgExt.Activity, GitgExt.Selectab public bool search_visible { get; set; } + private void update_search_path() + { + } + private void update_search_text() { if (d_repository_list_box != null) diff --git a/gitg/gitg-ui-elements.vala b/gitg/gitg-ui-elements.vala index 429ddf88..f22d8377 100644 --- a/gitg/gitg-ui-elements.vala +++ b/gitg/gitg-ui-elements.vala @@ -291,7 +291,8 @@ public class UIElements : Object public UIElements.with_builtin(T[] builtin, Peas.ExtensionSet extensions, - Gtk.Stack? stack = null) + Gtk.Stack? stack = null, + string? search_path = null) { d_extensions = extensions; d_stack = stack; @@ -304,7 +305,10 @@ public class UIElements : Object foreach (var b in builtin) { GitgExt.UIElement elem = (GitgExt.UIElement)b; - + if (elem is Gitg.DiffView) { + var diff_view = elem as Gitg.DiffView; + diff_view.search_path = search_path; + } d_builtin_elements[elem.id] = i++; add_ui_element(elem); } @@ -323,9 +327,9 @@ public class UIElements : Object } public UIElements(Peas.ExtensionSet extensions, - Gtk.Stack? stack = null) + Gtk.Stack? stack = null, string? search_path = null) { - this.with_builtin(new T[] {}, extensions, stack); + this.with_builtin(new T[] {}, extensions, stack, search_path); } } diff --git a/gitg/gitg-window.vala b/gitg/gitg-window.vala index f77a7f56..13564bd4 100644 --- a/gitg/gitg-window.vala +++ b/gitg/gitg-window.vala @@ -89,8 +89,9 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable [GtkChild] private unowned Gtk.SearchBar d_search_bar; [GtkChild] - private unowned Gtk.SearchEntry d_search_entry; - + private Gtk.SearchEntry d_search_entry_text; + [GtkChild] + private unowned Gtk.SearchEntry d_search_entry_path; [GtkChild] private unowned Gtk.Stack d_main_stack; @@ -242,11 +243,11 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable if (button.get_active()) { - d_search_entry.grab_focus_without_selecting(); + d_search_entry_text.grab_focus_without_selecting(); - d_search_entry.text = searchable.search_text; + d_search_entry_text.text = searchable.search_text; searchable.search_visible = true; - searchable.search_entry = d_search_entry; + searchable.search_entry = d_search_entry_text; } else { @@ -256,7 +257,7 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable } [GtkCallback] - private void search_entry_changed(Gtk.Editable entry) + private void search_entry_text_changed(Gtk.Editable entry) { var searchable = current_activity as GitgExt.Searchable; var ntext = ((Gtk.Entry) entry).text; @@ -267,6 +268,18 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable } } + [GtkCallback] + private void search_entry_path_changed(Gtk.Editable entry) + { + var searchable = current_activity as GitgExt.Searchable; + var ntext = (entry as Gtk.Entry).text; + + if (ntext != searchable.search_path) + { + searchable.search_path = ntext; + } + } + [GtkCallback] public bool on_key_pressed (Gtk.Widget widget, Gdk.EventKey event) { bool ret = d_search_bar.handle_event(event); @@ -323,7 +336,7 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable d_activities_model = Builder.load_object("ui/gitg-menus.ui", "win-menu-views"); // search bar - d_search_bar.connect_entry(d_search_entry); + d_search_bar.connect_entry(d_search_entry_text); d_search_button.bind_property("active", d_search_bar, "search-mode-enabled", @@ -813,7 +826,7 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable if (searchable != null) { d_search_button.visible = true; - d_search_entry.text = searchable.search_text; + d_search_entry_text.text = searchable.search_text; d_search_button.active = searchable.search_visible; d_searchable_available_binding = searchable.bind_property("search-available", @@ -827,7 +840,7 @@ public class Window : Gtk.ApplicationWindow, GitgExt.Application, Initable d_search_button.visible = false; d_search_button.active = false; d_search_button.sensitive = false; - d_search_entry.text = ""; + d_search_entry_text.text = ""; } var selectable = (current as GitgExt.Selectable); diff --git a/gitg/history/gitg-history.vala b/gitg/history/gitg-history.vala index 8257ae8b..c5fd558d 100644 --- a/gitg/history/gitg-history.vala +++ b/gitg/history/gitg-history.vala @@ -1238,6 +1238,17 @@ namespace GitgHistory } public string search_text { owned get; set; default = ""; } + private string d_search_path; + public string search_path + { + owned get { return d_search_path; } + set + { + d_search_path = value; + d_commit_list_model.search_path = d_search_path; + d_commit_list_model.reload(); + } + } public bool search_visible { get; set; } } } diff --git a/gitg/resources/ui/gitg-window.ui b/gitg/resources/ui/gitg-window.ui index 436c560a..5dc31d35 100644 --- a/gitg/resources/ui/gitg-window.ui +++ b/gitg/resources/ui/gitg-window.ui @@ -247,11 +247,44 @@ False False - + True - True - 500 - + horizontal + 6 + + + Text: + True + + + False + + + + + True + True + 500 + + + + + + Path: + True + + + False + + + + + True + True + 300 + + + diff --git a/libgitg-ext/gitg-ext-searchable.vala b/libgitg-ext/gitg-ext-searchable.vala index f49d5d6b..5e874b67 100644 --- a/libgitg-ext/gitg-ext-searchable.vala +++ b/libgitg-ext/gitg-ext-searchable.vala @@ -29,6 +29,7 @@ namespace GitgExt public interface Searchable : Object, Activity { public abstract string search_text { owned get; set; } + public abstract string search_path { owned get; set; } public abstract bool search_visible { get; set; } public abstract bool search_available { get; } public abstract Gtk.Entry? search_entry { set; } diff --git a/libgitg/gitg-cell-renderer-lanes.vala b/libgitg/gitg-cell-renderer-lanes.vala index f8f06dbb..acd937df 100644 --- a/libgitg/gitg-cell-renderer-lanes.vala +++ b/libgitg/gitg-cell-renderer-lanes.vala @@ -104,6 +104,10 @@ namespace Gitg foreach (var lane in commit.get_lanes()) { + if (!lane.interesting) + { + continue; + } var color = lane.color; context.set_source_rgb(color.r, color.g, color.b); @@ -137,6 +141,11 @@ namespace Gitg foreach (var lane in commit.get_lanes()) { + if (!lane.interesting) + { + continue; + } + if ((lane.tag & LaneTag.HIDDEN) != 0) { ++to; @@ -214,7 +223,7 @@ namespace Gitg context.set_source_rgb(0, 0, 0); context.stroke_preserve(); - if (commit.lane != null) + if (commit.lane != null && commit.lane.interesting) { var color = commit.lane.color; context.set_source_rgb(color.r, color.g, color.b); diff --git a/libgitg/gitg-commit-model.vala b/libgitg/gitg-commit-model.vala index 193a33fb..993b0bda 100644 --- a/libgitg/gitg-commit-model.vala +++ b/libgitg/gitg-commit-model.vala @@ -123,6 +123,8 @@ namespace Gitg _permanent_lanes = value; } + public string search_path { get; set; default=""; } + public signal void started(); public signal void update(uint added); public signal void finished(); @@ -418,7 +420,63 @@ namespace Gitg int mylane; SList lanes; - bool finded = d_lanes.next(commit, out lanes, out mylane, true); + var interesting = true; + if (search_path != null && search_path != "") + { + interesting = false; + var tree = commit.get_tree(); + Commit c = commit; + var opts = new Ggit.DiffOptions(); + opts.flags |= Ggit.DiffOption.IGNORE_WHITESPACE; + opts.flags |= Ggit.DiffOption.PATIENCE; + opts.n_context_lines = 3; + opts.n_interhunk_lines = 3; + opts.flags |= Ggit.DiffOption.SHOW_BINARY; + var diff = c.get_diff(opts, 0); + + var search_path_copy = search_path; + try { + diff.foreach( + (delta, progress) => { + var old_file_path = delta.get_old_file().get_path(); + var new_file_path = delta.get_new_file().get_path(); + if (new_file_path.contains(search_path_copy) || old_file_path.contains(search_path_copy)) { + return -7; + } + return 0; + }, + + (delta, binary) => { + return interesting ? -7: 0; + }, + + (delta, hunk) => { + return interesting ? -7: 0; + }, + + (delta, hunk, line) => { + return interesting ? -7: 0; + } + ); + + /* + tree.walk(Ggit.TreeWalkMode.PRE, (root, entry) => { + var file = root.concat(entry.get_name()); + var found = file.contains(search_path); + return found ? -7 : 0; + }); + */ + } catch (Error e) { + interesting = e.code == -7; + } + /* + if (!interesting) { + continue; + } + */ + } + + bool finded = d_lanes.next(commit, interesting, out lanes, out mylane, true); if (finded) { debug ("finded parent for %s %s\n", commit.get_subject(), commit.get_id().to_string()); @@ -450,7 +508,7 @@ namespace Gitg { var miss_commit = iter.get(); debug ("trying again %s %s", miss_commit.get_subject(), miss_commit.get_id().to_string()); - bool tmp_finded = d_lanes.next(miss_commit, out lanes, out mylane); + bool tmp_finded = d_lanes.next(miss_commit, interesting, out lanes, out mylane); if (tmp_finded) { finded = true; @@ -575,7 +633,7 @@ namespace Gitg public Gtk.TreeModelFlags get_flags() { return Gtk.TreeModelFlags.LIST_ONLY | - Gtk.TreeModelFlags.ITERS_PERSIST; + Gtk.TreeModelFlags.ITERS_PERSIST; } public bool get_iter(out Gtk.TreeIter iter, Gtk.TreePath path) diff --git a/libgitg/gitg-diff-view.vala b/libgitg/gitg-diff-view.vala index 0894bd26..7a98b62b 100644 --- a/libgitg/gitg-diff-view.vala +++ b/libgitg/gitg-diff-view.vala @@ -57,6 +57,7 @@ public class Gitg.DiffView : Gtk.Grid private uint d_reveal_options_timeout; private uint d_unreveal_options_timeout; + public string search_path { owned get; set; } private static Gee.HashSet s_image_mime_types; public Ggit.DiffOptions options @@ -773,6 +774,11 @@ public class Gitg.DiffView : Gtk.Grid return 1; } + var new_file_path = delta.get_new_file().get_path(); + var old_file_path = delta.get_old_file().get_path(); + if (search_path != null && search_path != "" && (!new_file_path.contains(search_path) || !old_file_path.contains(search_path))){ + return 0; + } add_file(); DiffViewFileInfo? info = null; diff --git a/libgitg/gitg-lane.vala b/libgitg/gitg-lane.vala index f73841be..69af7410 100644 --- a/libgitg/gitg-lane.vala +++ b/libgitg/gitg-lane.vala @@ -38,6 +38,7 @@ public class Lane : Object public SList from; public LaneTag tag; public Ggit.OId? boundary_id; + public bool interesting {get; set;} public Lane() { @@ -61,6 +62,7 @@ public class Lane : Object Lane ret = new Lane.with_color(color); ret.from = from.copy(); ret.tag = tag; + ret.interesting = interesting; ret.boundary_id = boundary_id; return ret; @@ -71,6 +73,7 @@ public class Lane : Object Lane ret = new Lane.with_color(color.copy()); ret.from = from.copy(); ret.tag = tag; + ret.interesting = interesting; ret.boundary_id = boundary_id; return ret; diff --git a/libgitg/gitg-lanes.vala b/libgitg/gitg-lanes.vala index 0deaf227..61510e48 100644 --- a/libgitg/gitg-lanes.vala +++ b/libgitg/gitg-lanes.vala @@ -37,6 +37,7 @@ public class Lanes : Object { public Lane lane; public int inactive; + public bool interesting {get; set; default=true; } public Ggit.OId? from; public Ggit.OId? to; @@ -47,6 +48,7 @@ public class Lanes : Object this.from = from; this.to = to; this.lane = new Lane.with_color(color); + this.lane.interesting = interesting; this.inactive = 0; } @@ -63,6 +65,7 @@ public class Lanes : Object lane.tag = LaneTag.NONE; lane.from = new SList(); + lane.interesting = interesting; if (!hidden) { @@ -155,7 +158,8 @@ public class Lanes : Object d_previous = new SList(); } - public bool next(Commit next, + public bool next(Commit next, + bool interesting, out SList lanes, out int nextpos, bool save_miss = false) @@ -185,6 +189,7 @@ public class Lanes : Object { // there is no lane reserved for this commit, add a new lane mylane = new LaneContainer(myoid, null); + mylane.interesting = interesting; d_lanes.add(mylane); nextpos = (int)d_lanes.size - 1; @@ -193,6 +198,8 @@ public class Lanes : Object { // copy the color here because the commit is a new stop mylane.lane.color = mylane.lane.color.copy(); + mylane.lane.interesting = interesting; + mylane.interesting = interesting; mylane.to = null; mylane.from = next.get_id();