Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/FolderManager/ProjectFolderItem.vala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

namespace Scratch.FolderManager {
// ProjectFolderItem represents the root folder usually of a repository
public class ProjectFolderItem : FolderItem {
struct VisibleItem {
public string rel_path;
Expand All @@ -26,14 +27,14 @@ namespace Scratch.FolderManager {

private static Icon added_icon;
private static Icon modified_icon;
// Cache the visible item in the project.
private List<VisibleItem?> visible_item_list = null;

public signal void closed ();
public signal void close_all_except ();

public Scratch.Services.MonitoredRepository? monitored_repo { get; private set; default = null; }
// Cache the visible item in the project.
private List<VisibleItem?> visible_item_list = null;
public string top_level_path { get; construct; }

public bool is_git_repo {
get {
return monitored_repo != null;
Expand Down Expand Up @@ -71,7 +72,6 @@ namespace Scratch.FolderManager {
}

construct {
monitored_repo = Scratch.Services.GitManager.get_instance ().add_project (this);
notify["name"].connect (branch_or_name_changed);
if (monitored_repo != null) {
monitored_repo.branch_changed.connect (branch_or_name_changed);
Expand All @@ -80,6 +80,8 @@ namespace Scratch.FolderManager {
monitored_repo.update_status_map ();
monitored_repo.branch_changed ();
}

monitored_repo = Scratch.Services.GitManager.get_instance ().add_project (this);
}

public void child_folder_changed (FolderItem folder) {
Expand Down
26 changes: 4 additions & 22 deletions src/Services/GitManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@

namespace Scratch.Services {
public class GitManager : Object {
public ListStore project_liststore { get; private set; }
public string active_project_path { get; set; default = "";}
public signal void project_added (FolderManager.ProjectFolderItem project);
public signal void project_removed (FolderManager.ProjectFolderItem project);

static Gee.HashMap<string, MonitoredRepository> project_gitrepo_map;
static GitManager? instance;
Expand All @@ -40,13 +41,7 @@ namespace Scratch.Services {
return instance;
}

private GitManager () {
project_liststore = new ListStore (typeof (FolderManager.ProjectFolderItem));
}

public MonitoredRepository? add_project (FolderManager.ProjectFolderItem root_folder) {
project_liststore.insert_sorted (root_folder, (CompareDataFunc<GLib.Object>) project_sort_func);

var root_path = root_folder.file.file.get_path ();
try {
var git_repo = Ggit.Repository.open (root_folder.file.file);
Expand All @@ -56,32 +51,19 @@ namespace Scratch.Services {

var monitored_repo = new MonitoredRepository (git_repo);
project_gitrepo_map.@set (root_path, monitored_repo);
project_added (root_folder);
return project_gitrepo_map.@get (root_path);
} catch (Error e) {
debug ("Error opening git repo for %s, means this probably isn't one: %s", root_path, e.message);
return null;
}
}

[CCode (instance_pos = -1)]
private int project_sort_func (FolderManager.ProjectFolderItem a, FolderManager.ProjectFolderItem b) {
GLib.File file_a = a.file.file;
GLib.File file_b = b.file.file;
return Path.get_basename (file_a.get_path ()).collate (Path.get_basename (file_b.get_path ()));
}

public void remove_project (FolderManager.ProjectFolderItem root_folder) {
var root_path = root_folder.file.file.get_path ();

uint position;
if (project_liststore.find (root_folder, out position)) {
project_liststore.remove (position);
} else {
critical ("Can't remove: %s", root_path);
}

if (project_gitrepo_map.has_key (root_path)) {
project_gitrepo_map.unset (root_path);
project_removed (root_folder);
}
}
}
Expand Down
94 changes: 53 additions & 41 deletions src/Widgets/ChooseProjectButton.vala
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
private Gtk.Label label_widget;
private Gtk.ListBox project_listbox;
private ProjectRow? last_entry = null;
private Scratch.Services.GitManager git_manager;

construct {
git_manager = Scratch.Services.GitManager.get_instance ();
var img = new Gtk.Image () {
gicon = new ThemedIcon ("git-symbolic"),
icon_size = Gtk.IconSize.SMALL_TOOLBAR
Expand All @@ -47,21 +49,30 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
project_listbox = new Gtk.ListBox () {
selection_mode = Gtk.SelectionMode.SINGLE
};

var project_filter = new Gtk.SearchEntry () {
margin = 12,
margin_top = 12,
margin_start = 12,
margin_end = 12,
margin_bottom = 6,
placeholder_text = _("Filter projects")
};

project_listbox.set_filter_func ((row) => {
//Both are lowercased so that the case doesn't matter when comparing.
return (((ProjectRow) row).project_name.down ().contains (project_filter.text.down ().strip ()));
});

project_filter.changed.connect (() => {
project_listbox.invalidate_filter ();
});

project_listbox.set_sort_func ((row1, row2) => {
var pr1 = (ProjectRow)row1;
var pr2 = (ProjectRow)row2;
return pr1.project_folder.name.collate (pr2.project_folder.name);
});

project_listbox.set_filter_func ((row) => {
var pr = (ProjectRow)row;
return pr.project_folder.name.down ().has_prefix (project_filter.text.down ().strip ());
});

var project_scrolled = new Gtk.ScrolledWindow (null, null) {
hscrollbar_policy = Gtk.PolicyType.NEVER,
expand = true,
Expand All @@ -71,6 +82,7 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
propagate_natural_height = true
};


project_scrolled.add (project_listbox);

var popover_content = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
Expand All @@ -87,31 +99,17 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {

popover = project_popover;

project_listbox.bind_model (
Scratch.Services.GitManager.get_instance ().project_liststore,
create_project_row
);

project_listbox.remove.connect ((row) => {
var project_row = row as ProjectRow;
var current_project = Scratch.Services.GitManager.get_instance ().active_project_path;
if (project_row.project_path == current_project) {
label_widget.label = _(NO_PROJECT_SELECTED);
label_widget.tooltip_text = _("Active Git project: %s").printf (_(NO_PROJECT_SELECTED));
Scratch.Services.GitManager.get_instance ().active_project_path = "";
}
});

git_manager.project_added.connect (create_project_row);
git_manager.project_removed.connect (remove_project_row);
project_listbox.row_activated.connect ((row) => {
var project_entry = ((ProjectRow) row);
select_project (project_entry);
select_project ((ProjectRow) row);
});
}

private Gtk.Widget create_project_row (GLib.Object object) {
unowned var project_folder = (Scratch.FolderManager.ProjectFolderItem) object;
private void create_project_row (
Scratch.FolderManager.ProjectFolderItem project_folder) {

var project_row = new ProjectRow (project_folder.file.file.get_path ());
var project_row = new ProjectRow (project_folder);
project_folder.bind_property ("name", project_row.project_radio, "label", BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE,
(binding, srcval, ref targetval) => {
var label = srcval.get_string ();
Expand All @@ -126,18 +124,33 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
if (last_entry != null) {
project_row.project_radio.join_group (last_entry.project_radio);
}

last_entry = project_row;
project_listbox.insert (project_row, -1);
project_listbox.invalidate_sort ();
}
private void remove_project_row (Scratch.FolderManager.ProjectFolderItem project_folder) {
foreach (Gtk.Widget child in project_listbox.get_children ()) {
if ((child is ProjectRow) &&
((ProjectRow)child).project_folder == project_folder) {

if (project_folder.path == git_manager.active_project_path) {
label_widget.label = _(NO_PROJECT_SELECTED);
label_widget.tooltip_text = _("Active Git project: %s").printf (_(NO_PROJECT_SELECTED));
git_manager.active_project_path = "";
}

return project_row;
remove (child);
}
}
}

private void select_project (ProjectRow project_entry) {
project_listbox.select_row (project_entry);
label_widget.label = project_entry.project_name;
var tooltip_text = Scratch.Utils.replace_home_with_tilde (project_entry.project_path);
private void select_project (ProjectRow project_selected) {
label_widget.label = project_selected.project_folder.name;
var tooltip_text = Scratch.Utils.replace_home_with_tilde (project_selected.project_folder.path);
label_widget.tooltip_text = _("Active Git project: %s").printf (tooltip_text);
project_entry.active = true;
Scratch.Services.GitManager.get_instance ().active_project_path = project_entry.project_path;
project_selected.active = true;
git_manager.active_project_path = project_selected.project_folder.path;
}

public void set_document (Scratch.Services.Document doc) {
Expand All @@ -147,26 +160,25 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
public void set_active_path (string active_path) {
project_listbox.get_children ().foreach ((child) => {
var project_entry = ((ProjectRow) child);
if (active_path.has_prefix (project_entry.project_path)) {
if (active_path.has_prefix (project_entry.project_folder.path)) {
select_project (project_entry);
}
});
}

public class ProjectRow : Gtk.ListBoxRow {
public bool active { get; set; }
public string project_path { get; construct; }
public string project_name {
public Scratch.FolderManager.ProjectFolderItem project_folder { get; construct; }
public Gtk.RadioButton project_radio { get; construct; }
public string label {
get {
return project_radio.label;
}
}

public Gtk.RadioButton project_radio { get; construct; }

public ProjectRow (string project_path) {
public ProjectRow (Scratch.FolderManager.ProjectFolderItem project_folder) {
Object (
project_path: project_path
project_folder: project_folder
);
}

Expand All @@ -175,7 +187,7 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
}

construct {
project_radio = new Gtk.RadioButton.with_label (null, Path.get_basename (project_path));
project_radio = new Gtk.RadioButton.with_label (null, project_folder.name);
add (project_radio);
show_all ();

Expand Down
4 changes: 2 additions & 2 deletions src/Widgets/SourceGutterRenderer.vala
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public class Scratch.Widgets.SourceGutterRenderer : Gtk.SourceGutterRenderer {
public Gee.HashMap<Services.VCStatus, Gdk.RGBA?> status_color_map;
public FolderManager.ProjectFolderItem? project { get; set; default = null; }
public string workdir_path {
get {
return project != null ? project.top_level_path : "";
owned get {
return project != null ? project.path : "";
}
}

Expand Down