Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Choose project popover #1030

Merged
merged 34 commits into from
May 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5352968
Add ChooseProjectButton class
May 15, 2021
7a2b03c
Add ChooseProjectButton to HeaderBar and react to add/remove project
May 16, 2021
298139e
ChooseProjectButton.vala: Update header
May 16, 2021
2ee3d6f
Fix lint
May 16, 2021
197be39
Use HeaderBar active project new-branch action
May 16, 2021
5af4ed9
Use ChooseProjectButton active project for find-global action
May 16, 2021
7aefcaa
Fix closing all except
May 16, 2021
84737c1
ChooseProjectButton: Expand horizontally, add top & bottom margins
May 17, 2021
aae4b4e
ChooseProjectButton: Limit width to 24 chars
May 19, 2021
2f596a0
Merge branch 'master' into choose-project-popover
May 19, 2021
c9a8a16
ChooseProjectButton: Set max chars and ellipsize
May 19, 2021
21ae87e
ChooseProjectButton: use max_content_height for scrolled (#1038)
danirabbit May 19, 2021
0881614
ChooseProjectButton: bind ProjectEntry radio to active (#1040)
danirabbit May 19, 2021
9154111
ChooseProjectButton: valign center (#1037)
danirabbit May 19, 2021
fdcbf79
ChooseProjectButton: subclass menubutton (#1039)
danirabbit May 19, 2021
4a964c9
Merge branch 'master' into choose-project-popover
May 19, 2021
86ba6f6
ChooseProjectButton.vala: Lose unused code
May 19, 2021
c1040c8
Show project path in tooltip
May 19, 2021
cb09a3f
Replace missing brace
May 19, 2021
b1765ce
ProjectEntry: Rename to ProjectRow
May 19, 2021
fb0cbca
Remove duplicated code
May 19, 2021
f3efbf7
Update src/Widgets/ChooseProjectButton.vala
May 19, 2021
99248a1
Update src/Widgets/ChooseProjectButton.vala: Explict get/set
May 19, 2021
014c05d
More concise names
May 19, 2021
4219468
Reduce scope if `img`
May 19, 2021
122028a
ChooseProjectButton: use a liststore to populate project list (#1042)
danirabbit May 20, 2021
0ccd722
Merge branch 'master' into choose-project-popover
May 20, 2021
02570fb
Update src/Widgets/HeaderBar.vala: remove unused setter
May 20, 2021
219c985
GitManager: source of truth for active_project_path (#1044)
May 20, 2021
0685c5a
ChooseProjectButton: simplify ProjectRow click handling (#1041)
danirabbit May 20, 2021
c17fbcc
Merge branch 'master' into choose-project-popover
May 20, 2021
6bf8716
Allow non-git projects to fix global search (#1045)
danirabbit May 21, 2021
8bd00df
Merge branch 'master' into choose-project-popover
May 23, 2021
8649ab6
Merge branch 'master' into choose-project-popover
danirabbit May 25, 2021
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
82 changes: 34 additions & 48 deletions src/Dialogs/NewBranchDialog.vala
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
*/

public class Scratch.Dialogs.NewBranchDialog : Granite.MessageDialog {
public FolderManager.ProjectFolderItem? active_project { get; construct; }
public unowned List<FolderManager.ProjectFolderItem> project_list { get; construct; }
public FolderManager.ProjectFolderItem active_project { get; construct; }

private Granite.ValidatedEntry new_branch_name_entry;
public string new_branch_name {
Expand All @@ -30,66 +29,53 @@ public class Scratch.Dialogs.NewBranchDialog : Granite.MessageDialog {
}
}

public NewBranchDialog (FolderManager.ProjectFolderItem? project, List<FolderManager.ProjectFolderItem> project_list) {
public NewBranchDialog (FolderManager.ProjectFolderItem project) {
Object (
transient_for: ((Gtk.Application)(GLib.Application.get_default ())).get_active_window (),
active_project: project,
project_list: project_list,
image_icon: new ThemedIcon ("git")
);
}

construct {
if (active_project != null) {
assert (active_project.is_git_repo);
primary_text = _("Create a new branch of “%s/%s”").printf (
active_project.file.file.get_basename (),
active_project.get_current_branch_name ()
);
///TRANSLATORS "Git" is a proper name and must not be translated
secondary_text = _("The branch name must be unique and follow Git naming rules.");
badge_icon = new ThemedIcon ("list-add");

new_branch_name_entry = new Granite.ValidatedEntry () {
activates_default = true
};

custom_bin.add (new_branch_name_entry);
assert (active_project.is_git_repo);
add_button (_("Cancel"), Gtk.ResponseType.CANCEL);
primary_text = _("Create a new branch of “%s/%s”").printf (
active_project.file.file.get_basename (),
active_project.get_current_branch_name ()
);
///TRANSLATORS "Git" is a proper name and must not be translated
secondary_text = _("The branch name must be unique and follow Git naming rules.");
badge_icon = new ThemedIcon ("list-add");
new_branch_name_entry = new Granite.ValidatedEntry () {
activates_default = true
};

var create_button = (Gtk.Button) add_button (_("Create Branch"), Gtk.ResponseType.APPLY);
create_button.can_default = true;
create_button.has_default = true;
create_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
custom_bin.add (new_branch_name_entry);

new_branch_name_entry.bind_property (
"is-valid", create_button, "sensitive", BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE
);
var create_button = (Gtk.Button) add_button (_("Create Branch"), Gtk.ResponseType.APPLY);
create_button.can_default = true;
create_button.has_default = true;
create_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);

new_branch_name_entry.changed.connect (() => {
unowned var new_name = new_branch_name_entry.text;
if (!active_project.is_valid_new_branch_name (new_name)) {
new_branch_name_entry.is_valid = false;
return;
}
new_branch_name_entry.bind_property (
"is-valid", create_button, "sensitive", BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE
);

if (active_project.has_local_branch_name (new_name)) {
new_branch_name_entry.is_valid = false;
return;
}
new_branch_name_entry.changed.connect (() => {
unowned var new_name = new_branch_name_entry.text;
if (!active_project.is_valid_new_branch_name (new_name)) {
new_branch_name_entry.is_valid = false;
return;
}

//Do we need to check remote branches as well?
new_branch_name_entry.is_valid = true;
});
} else {
primary_text = _("You must have an active Git project before creating a new branch.");
badge_icon = new ThemedIcon ("dialog-warning");
if (project_list.length () == 0) {
secondary_text = _("Open a Git project folder in the sidebar.");
} else {
secondary_text = _("Open a document in a Git project folder in the sidebar or use a project context menu.");
if (active_project.has_local_branch_name (new_name)) {
new_branch_name_entry.is_valid = false;
return;
}
}

add_button (_("Cancel"), Gtk.ResponseType.CANCEL);
//Do we need to check remote branches as well?
new_branch_name_entry.is_valid = true;
});
}
}
51 changes: 15 additions & 36 deletions src/FolderManager/FileView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -163,50 +163,26 @@ namespace Scratch.FolderManager {
}
}

public void new_branch (GLib.File? current_doc_file) {
GLib.List<ProjectFolderItem> project_list;
public void new_branch (string active_project_path) {
unowned var active_project = (ProjectFolderItem)(find_path (root, active_project_path));
if (active_project == null || !active_project.is_git_repo) {
Gdk.beep ();
return;
}

string? branch_name = null;
unowned var active_project = get_active_project (current_doc_file, out project_list);
var dialog = new Dialogs.NewBranchDialog (active_project, project_list);
var dialog = new Dialogs.NewBranchDialog (active_project);
dialog.show_all ();
if (dialog.run () == Gtk.ResponseType.APPLY) {
branch_name = dialog.new_branch_name;
}

dialog.destroy ();
if (active_project != null && branch_name != null) {
if (branch_name != null) {
active_project.new_branch (branch_name);
}
}

public unowned ProjectFolderItem? get_active_project (GLib.File? active_file, out List<ProjectFolderItem> project_list) {
unowned ProjectFolderItem? project = null;
project_list = null;
foreach (var child in root.children) {
project = (ProjectFolderItem)child;
if (!project.is_git_repo) {
// Ignore sidebar folders that are not git repos
continue;
}

if (active_file != null)
if (project.file.file.equal (active_file) ||
project.file.file.get_relative_path (active_file) != null) {

return project;
}

project_list.prepend (project);
}

if (project_list.length () == 1) {
//There was only one project so use that
return project_list.data;
}

return null;
}

private void add_folder (File folder, bool expand) {
if (is_open (folder)) {
warning ("Folder '%s' is already open.", folder.path);
Expand All @@ -216,20 +192,23 @@ namespace Scratch.FolderManager {
return;
}

var folder_root = new ProjectFolderItem (folder, this);
var folder_root = new ProjectFolderItem (folder, this); // Constructor adds project to GitManager
this.root.add (folder_root);

folder_root.expanded = expand;
folder_root.closed.connect (() => {
close_all_docs_from_path (folder_root.file.path);
root.remove (folder_root);
Scratch.Services.GitManager.get_instance ().remove_project (folder_root.file.file);
write_settings ();
});

folder_root.close_all_except.connect (() => {
foreach (var child in root.children) {
if (child != folder_root) {
root.remove (child);
var project_folder_item = (ProjectFolderItem)child;
if (project_folder_item != folder_root) {
root.remove (project_folder_item);
Scratch.Services.GitManager.get_instance ().remove_project (project_folder_item.file.file);
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/FolderManager/ProjectFolderItem.vala
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ namespace Scratch.FolderManager {

public override Gtk.Menu? get_context_menu () {
var close_item = new Gtk.MenuItem.with_label (_("Close Folder"));
close_item.activate.connect (() => { closed (); });
close_item.activate.connect (() => {
closed ();
});

var close_all_except_item = new Gtk.MenuItem.with_label (_("Close Other Folders"));
close_all_except_item.activate.connect (() => { close_all_except (); });
Expand Down
54 changes: 24 additions & 30 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -876,19 +876,7 @@ namespace Scratch {
}

private void action_find_global (SimpleAction action, Variant? param) {
string path = "";
if (param != null) {
path = param.get_string ();
}

if (path == "") {
var current_doc = get_current_document ();
if (current_doc != null) {
path = current_doc.file.get_path ();
}
}

folder_manager_view.search_global (path);
folder_manager_view.search_global (get_target_path_for_git_actions (param));
}

private void set_search_text () {
Expand Down Expand Up @@ -1006,22 +994,28 @@ namespace Scratch {
}

private void action_new_branch (SimpleAction action, Variant? param) {
string path = "";
File? file = null;
if (param != null) {
path = param.get_string ();
}

if (path == "") {
var current_doc = get_current_document ();
if (current_doc != null) {
file = current_doc.file;
}
} else {
file = File.new_for_path (path);
}

folder_manager_view.new_branch (file);
}
folder_manager_view.new_branch (get_target_path_for_git_actions (param));
}

private string? get_target_path_for_git_actions (Variant? path_variant) {
string? path = "";
if (path_variant != null) {
path = path_variant.get_string ();
}

if (path == "") { // Happens when keyboard accelerator is used
path = Services.GitManager.get_instance ().active_project_path;
if (path == null) {
var current_doc = get_current_document ();
if (current_doc != null) {
path = current_doc.file.get_path ();
} else {
return null; // Cannot determine target project
}
}
}

return path;
}
}
}
22 changes: 21 additions & 1 deletion src/Services/GitManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

namespace Scratch.Services {
public class GitManager : Object {
public ListStore project_liststore { get; private set; }
public string active_project_path { get; set; default = "";}

static Gee.HashMap<string, MonitoredRepository> project_gitrepo_map;
static GitManager? instance;

Expand All @@ -37,9 +40,13 @@ namespace Scratch.Services {
return instance;
}

private GitManager () {}
private GitManager () {
project_liststore = new ListStore (typeof (File));
}

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

var root_path = root_folder.get_path ();
try {
var git_repo = Ggit.Repository.open (root_folder);
Expand All @@ -57,8 +64,21 @@ namespace Scratch.Services {
}
}

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

public void remove_project (GLib.File root_folder) {
var root_path = root_folder.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);
}
Expand Down
Loading