diff --git a/data/io.elementary.code.gschema.xml b/data/io.elementary.code.gschema.xml
index 400fe64e4..397b293ed 100644
--- a/data/io.elementary.code.gschema.xml
+++ b/data/io.elementary.code.gschema.xml
@@ -152,6 +152,11 @@
Remember the last focused document.
Restore the focused document from a previous session when opening Code.
+
+ ''
+ The active project path.
+ The path to the folder containing the active project.
+
''
The default build directory's relative path.
diff --git a/src/FolderManager/FileView.vala b/src/FolderManager/FileView.vala
index c65170249..d251e0396 100644
--- a/src/FolderManager/FileView.vala
+++ b/src/FolderManager/FileView.vala
@@ -35,6 +35,7 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane
public const string ACTION_CHANGE_BRANCH = "change-branch";
public const string ACTION_CLOSE_FOLDER = "close-folder";
public const string ACTION_CLOSE_OTHER_FOLDERS = "close-other-folders";
+ public const string ACTION_SET_ACTIVE_PROJECT = "set-active-project";
private const ActionEntry[] ACTION_ENTRIES = {
{ ACTION_LAUNCH_APP_WITH_FILE_PATH, action_launch_app_with_file_path, "as" },
@@ -46,7 +47,8 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane
{ ACTION_NEW_FILE, add_new_file, "s" },
{ ACTION_NEW_FOLDER, add_new_folder, "s"},
{ ACTION_CLOSE_FOLDER, action_close_folder, "s"},
- { ACTION_CLOSE_OTHER_FOLDERS, action_close_other_folders, "s"}
+ { ACTION_CLOSE_OTHER_FOLDERS, action_close_other_folders, "s"},
+ { ACTION_SET_ACTIVE_PROJECT, action_set_active_project, "s"}
};
private GLib.Settings settings;
@@ -60,11 +62,6 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane
public ActionGroup toplevel_action_group { get; private set; }
public string icon_name { get; set; }
public string title { get; set; }
- public string active_project_path {
- get {
- return git_manager.active_project_path;
- }
- }
public FileView (Scratch.Services.PluginsManager plugins_manager) {
plugins = plugins_manager;
@@ -119,10 +116,29 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane
if (project_folder_item != folder_root) {
toplevel_action_group.activate_action (MainWindow.ACTION_CLOSE_PROJECT_DOCS, new Variant.string (project_folder_item.path));
root.remove (project_folder_item);
- Scratch.Services.GitManager.get_instance ().remove_project (project_folder_item);
+ git_manager.remove_project (project_folder_item);
}
}
+ //Make remaining project the active one
+ git_manager.active_project_path = path;
+
+ write_settings ();
+ }
+
+ private void action_set_active_project (SimpleAction action, GLib.Variant? parameter) {
+ var path = parameter.get_string ();
+ if (path == null || path == "") {
+ return;
+ }
+
+ var folder_root = find_path (root, path) as ProjectFolderItem;
+ if (folder_root == null) {
+ return;
+ }
+
+ git_manager.active_project_path = path;
+
write_settings ();
}
@@ -176,14 +192,9 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane
selected = null;
}
- public void collapse_other_projects (string? keep_open_path = null) {
+ public void collapse_other_projects () {
unowned string path;
- if (keep_open_path == null) {
- path = git_manager.active_project_path;
- } else {
- path = keep_open_path;
- git_manager.active_project_path = path;
- }
+ path = git_manager.active_project_path;
foreach (var child in root.children) {
var project_folder = ((ProjectFolderItem) child);
diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala
index fd9dbaa71..e28fc381a 100644
--- a/src/FolderManager/ProjectFolderItem.vala
+++ b/src/FolderManager/ProjectFolderItem.vala
@@ -134,16 +134,28 @@ namespace Scratch.FolderManager {
warning (e.message);
}
- var open_in_terminal_pane_item = new GLib.MenuItem (
- _("Open in Terminal Pane"),
- GLib.Action.print_detailed_name (
- MainWindow.ACTION_PREFIX + MainWindow.ACTION_OPEN_IN_TERMINAL,
- new Variant.string (
- Services.GitManager.get_instance ().get_default_build_dir (path)
+ MenuItem set_active_folder_item;
+ if (is_git_repo) {
+ set_active_folder_item = new GLib.MenuItem (
+ _("Set as Active Project"),
+ GLib.Action.print_detailed_name (
+ FileView.ACTION_PREFIX + FileView.ACTION_SET_ACTIVE_PROJECT,
+ new Variant.string (file.path)
)
- )
- );
- open_in_terminal_pane_item.set_attribute_value (
+ );
+ } else {
+ set_active_folder_item = new GLib.MenuItem (
+ _("Open in Terminal Pane"),
+ GLib.Action.print_detailed_name (
+ MainWindow.ACTION_PREFIX + MainWindow.ACTION_OPEN_IN_TERMINAL,
+ new Variant.string (
+ Services.GitManager.get_instance ().get_default_build_dir (path)
+ )
+ )
+ );
+ }
+
+ set_active_folder_item.set_attribute_value (
"accel",
Utils.get_accel_for_action (
GLib.Action.print_detailed_name (
@@ -154,7 +166,7 @@ namespace Scratch.FolderManager {
);
var external_actions_section = new GLib.Menu ();
- external_actions_section.append_item (open_in_terminal_pane_item);
+ external_actions_section.append_item (set_active_folder_item);
external_actions_section.append_item (create_submenu_for_open_in (file_type));
var folder_actions_section = new GLib.Menu ();
diff --git a/src/MainWindow.vala b/src/MainWindow.vala
index edab76705..79cb34045 100644
--- a/src/MainWindow.vala
+++ b/src/MainWindow.vala
@@ -27,6 +27,17 @@ namespace Scratch {
public Scratch.Application app { get; private set; }
public bool restore_docs { get; construct; }
public RestoreOverride restore_override { get; construct set; }
+ public string default_globalsearch_path {
+ owned get {
+ if (document_view.current_document != null) {
+ if (document_view.current_document.project_path != "") {
+ return document_view.current_document.project_path;
+ }
+ }
+
+ return git_manager.active_project_path;
+ }
+ }
public Scratch.Widgets.DocumentView document_view;
@@ -610,7 +621,6 @@ namespace Scratch {
title = _("%s - %s").printf (doc.get_basename (), base_title);
toolbar.set_document_focus (doc);
- git_manager.active_project_path = doc.source_view.project.path;
folder_manager_view.select_path (doc.file.get_path ());
// Must follow setting focus document for editorconfig plug
@@ -1204,8 +1214,10 @@ namespace Scratch {
}
private void action_find_global (SimpleAction action, Variant? param) {
+ var selected_text = "";
+ var search_path = "";
+
var current_doc = get_current_document ();
- string selected_text = "";
if (current_doc != null) {
selected_text = current_doc.get_selected_text (false);
}
@@ -1225,7 +1237,19 @@ namespace Scratch {
term = search_bar.search_entry.text;
}
- folder_manager_view.search_global (get_target_path_for_actions (param), term);
+ if (param != null && param.get_string () != "") {
+ search_path = param.get_string ();
+ } else {
+ search_path = default_globalsearch_path;
+ }
+
+ if (search_path != "") {
+ folder_manager_view.search_global (search_path, term);
+ } else {
+ // Fallback to standard search
+ warning ("Unable to perform global search - search document instead");
+ action_fetch (action, param);
+ }
}
private void update_find_actions () {
@@ -1236,9 +1260,9 @@ namespace Scratch {
Utils.action_from_group (ACTION_SHOW_FIND, actions).set_enabled (is_current_doc);
Utils.action_from_group (ACTION_FIND_NEXT, actions).set_enabled (is_current_doc);
Utils.action_from_group (ACTION_FIND_PREVIOUS, actions).set_enabled (is_current_doc);
+ var can_global_search = is_current_doc || git_manager.active_project_path != null;
+ Utils.action_from_group (ACTION_FIND_GLOBAL, actions).set_enabled (can_global_search);
- var is_active_project = git_manager.active_project_path != "";
- Utils.action_from_group (ACTION_FIND_GLOBAL, actions).set_enabled (is_active_project);
return Source.REMOVE;
});
}
diff --git a/src/Services/Document.vala b/src/Services/Document.vala
index 20fae404a..528570095 100644
--- a/src/Services/Document.vala
+++ b/src/Services/Document.vala
@@ -65,6 +65,16 @@ namespace Scratch.Services {
}
}
+ public string project_path {
+ owned get {
+ if (source_view.project != null) {
+ return source_view.project.path;
+ } else {
+ return "";
+ }
+ }
+ }
+
private string _title = "";
public string title {
get { return _title; }
diff --git a/src/Services/GitManager.vala b/src/Services/GitManager.vala
index 6001473cf..3b43bb88a 100644
--- a/src/Services/GitManager.vala
+++ b/src/Services/GitManager.vala
@@ -44,9 +44,10 @@ namespace Scratch.Services {
return instance;
}
- private GitManager () {
+ construct {
// Used to populate the ChooseProject popover in sorted order
project_liststore = new ListStore (typeof (FolderManager.ProjectFolderItem));
+ settings.bind ("active-project-path", this, "active-project-path", DEFAULT);
}
public MonitoredRepository? add_project (FolderManager.ProjectFolderItem root_folder) {
@@ -72,8 +73,7 @@ namespace Scratch.Services {
);
}
- //Ensure active_project_path always set
- active_project_path = root_path;
+ // No longer need to set default project (restored from settings or left unset)
return project_gitrepo_map.@get (root_path);
}
diff --git a/src/Widgets/ChooseProjectButton.vala b/src/Widgets/ChooseProjectButton.vala
index 79f597435..90fba9259 100644
--- a/src/Widgets/ChooseProjectButton.vala
+++ b/src/Widgets/ChooseProjectButton.vala
@@ -18,18 +18,9 @@
public class Code.ChooseProjectButton : Gtk.MenuButton {
private const string NO_PROJECT_SELECTED = N_("No Project Selected");
+ private const string PROJECT_TOOLTIP = N_("Active Git Project: %s");
private Gtk.Label label_widget;
private Gtk.ListBox project_listbox;
- public unowned Gtk.RadioButton? group_source {
- get {
- var first_row = project_listbox.get_row_at_index (0);
- if (first_row != null) {
- return ((ProjectRow)first_row).project_radio;
- } else {
- return null;
- }
- }
- }
public signal void project_chosen ();
@@ -44,8 +35,6 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
xalign = 0.0f
};
- tooltip_text = _("Active Git project: %s").printf (_(NO_PROJECT_SELECTED));
-
var grid = new Gtk.Grid () {
halign = Gtk.Align.START
};
@@ -97,6 +86,7 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
popover = project_popover;
var git_manager = Scratch.Services.GitManager.get_instance ();
+
git_manager.project_liststore.items_changed.connect ((src, pos, n_removed, n_added) => {
var rows = project_listbox.get_children ();
for (int index = (int)pos; index < pos + n_removed; index++) {
@@ -111,89 +101,80 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
project_listbox.insert (row, index);
}
}
-
- set_active_path (git_manager.active_project_path);
- });
-
- git_manager.notify["active-project-path"].connect (() => {
- set_active_path (git_manager.active_project_path);
});
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 = "";
+ // Label and active_path will be updated automatically
}
});
project_listbox.row_activated.connect ((row) => {
var project_entry = ((ProjectRow) row);
- label_widget.label = project_entry.project_name;
- var tooltip_text = Scratch.Utils.replace_home_with_tilde (project_entry.project_path);
- label_widget.tooltip_text = _("Active Git project: %s").printf (tooltip_text);
- Scratch.Services.GitManager.get_instance ().active_project_path = project_entry.project_path;
- project_entry.active = true;
+ git_manager.active_project_path = project_entry.project_path;
project_chosen ();
});
- }
- private void set_active_path (string active_path) {
- foreach (var child in project_listbox.get_children ()) {
- var project_entry = ((ProjectRow) child);
- if (active_path.has_prefix (project_entry.project_path + Path.DIR_SEPARATOR_S)) {
- project_listbox.row_activated (project_entry);
- break;
+ toggled.connect (() => {
+ if (active) {
+ unowned var active_path = Scratch.Services.GitManager.get_instance ().active_project_path;
+ foreach (var child in project_listbox.get_children ()) {
+ var project_row = ((ProjectRow) child);
+ // All paths must not end in directory separator so can be compared directly
+ project_row.active = active_path == project_row.project_path;
+ }
}
+ });
+
+ git_manager.notify["active-project-path"].connect (update_button);
+ update_button ();
+ }
+
+ // Set appearance (only) of project chooser button and list according to active path
+ private void update_button () {
+ unowned var active_path = Scratch.Services.GitManager.get_instance ().active_project_path;
+ if (active_path != "") {
+ label_widget.label = Path.get_basename (active_path);
+ tooltip_text = _(PROJECT_TOOLTIP).printf (Scratch.Utils.replace_home_with_tilde (active_path));
+ } else {
+ label_widget.label = Path.get_basename (_(NO_PROJECT_SELECTED));
+ tooltip_text = _(PROJECT_TOOLTIP).printf (_(NO_PROJECT_SELECTED));
}
}
private Gtk.Widget create_project_row (Scratch.FolderManager.ProjectFolderItem project_folder) {
- var project_row = new ProjectRow (project_folder.file.file.get_path (), group_source);
- // Handle renaming of project;
- project_folder.bind_property ("name", project_row.project_radio, "label", BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE,
- (binding, srcval, ref targetval) => {
- var label = srcval.get_string ();
- targetval.set_string (label);
- if (project_row.active) {
- label_widget.label = label;
- }
-
- return true;
- }
- );
+ var project_path = project_folder.file.file.get_path ();
+ var project_row = new ProjectRow (project_path);
+ // Project folder items cannot be renamed in UI, no need to handle
return project_row;
}
public class ProjectRow : Gtk.ListBoxRow {
+ private Gtk.CheckButton check_button;
public bool active {
get {
- return project_radio.active;
+ return check_button.active;
}
set {
- if (value) {
- project_radio.active = true;
- }
+ check_button.active = value;
}
}
public string project_path { get; construct; }
public string project_name {
get {
- return project_radio.label;
+ return check_button.label;
}
}
- public Gtk.RadioButton project_radio { get; construct; }
-
- public ProjectRow (string project_path, Gtk.RadioButton? group_source ) {
+ public ProjectRow (string project_path) {
Object (
- project_path: project_path,
- project_radio: new Gtk.RadioButton.with_label_from_widget (group_source, Path.get_basename (project_path))
+ project_path: project_path
);
}
@@ -202,8 +183,9 @@ public class Code.ChooseProjectButton : Gtk.MenuButton {
}
construct {
- add (project_radio);
- project_radio.button_release_event.connect (() => {
+ check_button = new Gtk.CheckButton.with_label (Path.get_basename (project_path));
+ add (check_button);
+ check_button.button_release_event.connect (() => {
activate ();
return Gdk.EVENT_PROPAGATE;
});
diff --git a/src/Widgets/DocumentView.vala b/src/Widgets/DocumentView.vala
index ed19bb651..f45fc16ab 100644
--- a/src/Widgets/DocumentView.vala
+++ b/src/Widgets/DocumentView.vala
@@ -127,10 +127,11 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
} else {
doc.do_close.begin (false, (obj, res) => {
var should_close = doc.do_close.end (res);
- if (should_close) {
- before_doc_removed (doc);
+ // Ensure removed doc is saved by handling this first
+ if (!is_closing) {
+ save_opened_files ();
}
-
+ //`page-detached` handler will perform rest of necessary cleanup
tab_view.close_page_finish (tab, should_close);
});
}
@@ -139,7 +140,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
});
tab_view.page_attached.connect (on_doc_added);
- tab_view.page_detached.connect (on_doc_removed);
+ tab_view.page_detached.connect (on_page_detached);
tab_view.page_reordered.connect (on_doc_reordered);
tab_view.create_window.connect (on_doc_to_new_window);
@@ -463,21 +464,12 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
return unsaved_file_path_builder (extension);
}
- private void before_doc_removed (Services.Document doc) {
- on_doc_removed_shared (doc);
- }
-
- private void on_doc_removed (Hdy.TabPage tab, int position) {
+ private void on_page_detached (Hdy.TabPage tab, int position) {
var doc = tab.get_child () as Services.Document;
if (doc == null) {
return;
}
- on_doc_removed_shared (doc);
- request_placeholder_if_empty ();
- }
-
- private void on_doc_removed_shared (Services.Document doc) {
if (tab_history_button.menu_model == null) {
tab_history_button.menu_model = new Menu ();
}
@@ -522,9 +514,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
}
}
- if (!is_closing) {
- save_opened_files ();
- }
+ request_placeholder_if_empty ();
}
public void restore_closed_tab (string path) {