diff --git a/data/io.elementary.code.gschema.xml b/data/io.elementary.code.gschema.xml
index 0f78a64f7..58e76f580 100644
--- a/data/io.elementary.code.gschema.xml
+++ b/data/io.elementary.code.gschema.xml
@@ -58,6 +58,11 @@
Terminal visibility
Whether or not the terminal pane is visible
+
+ true
+ Sort open projects
+ Keep the open projects in alphabetical order
+
''
Last opened path
diff --git a/plugins/fuzzy-search/fuzzy-search.vala b/plugins/fuzzy-search/fuzzy-search.vala
index 41ebeec14..21fc73e54 100644
--- a/plugins/fuzzy-search/fuzzy-search.vala
+++ b/plugins/fuzzy-search/fuzzy-search.vala
@@ -10,11 +10,11 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Scratch.Services.A
public Object object { owned get; set construct; }
private const uint ACCEL_KEY = Gdk.Key.F;
private const Gdk.ModifierType ACCEL_MODTYPE = Gdk.ModifierType.MOD1_MASK;
+ private const string FUZZY_FINDER_ID = "fuzzy-finder";
private Scratch.Services.FuzzySearchIndexer indexer;
private MainWindow window = null;
private Scratch.Services.Interface plugins;
- private GLib.MenuItem fuzzy_menuitem;
private GLib.Cancellable cancellable;
private const string ACTION_GROUP = "fuzzysearch";
@@ -28,9 +28,11 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Scratch.Services.A
private GLib.Settings folder_settings;
private static Gee.MultiMap action_accelerators = new Gee.HashMultiMap ();
+ private static string accel_string;
static construct {
- action_accelerators.set (ACTION_SHOW, @"$(Gdk.keyval_name (ACCEL_KEY))");
+ accel_string = @"$(Gdk.keyval_name (ACCEL_KEY))";
+ action_accelerators.set (ACTION_SHOW, accel_string);
}
public void update_state () {
@@ -88,25 +90,22 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Scratch.Services.A
handle_opened_projects_change ();
- fuzzy_menuitem = new GLib.MenuItem (_("Find Project Files"), ACTION_PREFIX + ACTION_SHOW );
-
- var menu = window.sidebar.project_menu_model as GLib.Menu;
- menu.append_item (fuzzy_menuitem);
+ var label = new Granite.AccelLabel (_("Find Project Files")) {
+ action_name = ACTION_PREFIX + ACTION_SHOW,
+ accel_string = accel_string
+ };
+ var fuzzy_menuitem = new Gtk.Button () { // Cannot change child of ModelButton
+ action_name = ACTION_PREFIX + ACTION_SHOW,
+ child = label
+ };
+ fuzzy_menuitem.get_style_context ().add_class ("flat");
+
+ window.sidebar.add_project_menu_widget (FUZZY_FINDER_ID, fuzzy_menuitem);
}
private void remove_actions () {
- var sidebar_menu = window.sidebar.project_menu_model as GLib.Menu;
- int length = sidebar_menu.get_n_items ();
- for (var i = length - 1; i >= 0; i--) {
- var action_name = sidebar_menu.get_item_attribute_value (
- i,
- GLib.Menu.ATTRIBUTE_ACTION,
- GLib.VariantType.STRING
- ).get_string ();
- if (action_name.has_prefix (ACTION_PREFIX)) {
- sidebar_menu.remove (i);
- }
- }
+ var sidebar_menu = window.sidebar.project_menu;
+ window.sidebar.remove_project_menu_widget (FUZZY_FINDER_ID);
var application = (Gtk.Application) GLib.Application.get_default ();
var app = (Scratch.Application) application;
diff --git a/src/FolderManager/FileView.vala b/src/FolderManager/FileView.vala
index 2bb5035b3..eff964a15 100644
--- a/src/FolderManager/FileView.vala
+++ b/src/FolderManager/FileView.vala
@@ -63,6 +63,7 @@ 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 bool order_folders { get; set; default = true; }
public FileView (Scratch.Services.PluginsManager plugins_manager) {
plugins = plugins_manager;
@@ -85,6 +86,12 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane
toplevel_action_group = get_action_group (MainWindow.ACTION_GROUP);
assert_nonnull (toplevel_action_group);
});
+
+ notify["order-folders"].connect (() => {
+ if (order_folders) {
+ reorder_folders ();
+ }
+ });
}
private void action_close_folder (SimpleAction action, GLib.Variant? parameter) {
@@ -168,9 +175,9 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane
}
}
- public void order_folders () {
+ private void reorder_folders () {
+ // This is not efficient but SourceList does not currently allow `insert_sorted` or setting a sort function
var list = new Gee.ArrayList ();
-
foreach (var child in root.children) {
root.remove (child as ProjectFolderItem);
list.add (child as ProjectFolderItem);
@@ -567,8 +574,12 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane
// Process any closed signals emitted before proceeding
Idle.add (() => {
var folder_root = new ProjectFolderItem (folder, this); // Constructor adds project to GitManager
- this.root.add (folder_root);
+ this.root.add (folder_root); // TODO Implement add_sorted;
rename_items_with_same_name (folder_root);
+ if (order_folders) {
+ reorder_folders ();
+ }
+
folder_root.expanded = expand;
folder_root.closed.connect (() => {
diff --git a/src/MainWindow.vala b/src/MainWindow.vala
index bcf37aeb6..ecf6d0e60 100644
--- a/src/MainWindow.vala
+++ b/src/MainWindow.vala
@@ -141,7 +141,7 @@ namespace Scratch {
{ ACTION_OPEN_FOLDER, action_open_folder, "s" },
{ ACTION_OPEN_PROJECT, action_open_project },
{ ACTION_COLLAPSE_ALL_FOLDERS, action_collapse_all_folders },
- { ACTION_ORDER_FOLDERS, action_order_folders },
+ { ACTION_ORDER_FOLDERS, action_order_folders, null, "true" },
{ ACTION_PREFERENCES, action_preferences },
{ ACTION_REVERT, action_revert },
{ ACTION_SAVE, action_save },
@@ -347,6 +347,9 @@ namespace Scratch {
sidebar_action.set_state (saved_state.get_boolean ("sidebar-visible"));
update_toolbar_button (ACTION_TOGGLE_SIDEBAR, saved_state.get_boolean ("sidebar-visible"));
+ var order_folders_action = Utils.action_from_group (ACTION_ORDER_FOLDERS, actions);
+ order_folders_action.set_state (saved_state.get_boolean ("order-folders"));
+
var outline_action = Utils.action_from_group (ACTION_TOGGLE_OUTLINE, actions);
outline_action.set_state (saved_state.get_boolean ("outline-visible"));
update_toolbar_button (ACTION_TOGGLE_OUTLINE, saved_state.get_boolean ("outline-visible"));
@@ -567,6 +570,7 @@ namespace Scratch {
Scratch.saved_state.bind ("sidebar-visible", sidebar, "visible", SettingsBindFlags.DEFAULT);
Scratch.saved_state.bind ("outline-visible", document_view , "outline_visible", SettingsBindFlags.DEFAULT);
Scratch.saved_state.bind ("terminal-visible", terminal, "visible", SettingsBindFlags.DEFAULT);
+ Scratch.saved_state.bind ("order-folders", folder_manager_view, "order-folders", SettingsBindFlags.DEFAULT);
// Plugins hook
HookFunc hook_func = () => {
plugins.hook_window (this);
@@ -1126,7 +1130,10 @@ namespace Scratch {
}
private void action_order_folders () {
- folder_manager_view.order_folders ();
+ var action = Utils.action_from_group (ACTION_ORDER_FOLDERS, actions);
+ var to_show = !action.get_state ().get_boolean ();
+ action.set_state (to_show);
+ folder_manager_view.order_folders = to_show;
}
private void action_save () {
diff --git a/src/Widgets/Sidebar.vala b/src/Widgets/Sidebar.vala
index 2f95327ea..1af0be81c 100644
--- a/src/Widgets/Sidebar.vala
+++ b/src/Widgets/Sidebar.vala
@@ -25,7 +25,9 @@ public class Code.Sidebar : Gtk.Grid {
public Gtk.Stack stack { get; private set; }
public Code.ChooseProjectButton choose_project_button { get; private set; }
public Hdy.HeaderBar headerbar { get; private set; }
- public GLib.MenuModel project_menu_model { get; construct; }
+ public Gtk.Box project_menu { get; private set; }
+ private HashTable project_menu_map;
+ private Gtk.Separator project_menu_separator; // Divides plugin items from core items
// May show progress in different way in future
public bool cloning_in_progress {
get {
@@ -77,25 +79,28 @@ public class Code.Sidebar : Gtk.Grid {
var actionbar = new Gtk.ActionBar ();
actionbar.get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR);
- var collapse_all_menu_item = new GLib.MenuItem (_("Collapse All"), Scratch.MainWindow.ACTION_PREFIX
- + Scratch.MainWindow.ACTION_COLLAPSE_ALL_FOLDERS);
+ var collapse_all_menu_item = new Gtk.ModelButton () {
+ text = _("Collapse All"),
+ action_name = Scratch.MainWindow.ACTION_PREFIX + Scratch.MainWindow.ACTION_COLLAPSE_ALL_FOLDERS
+ };
- var order_projects_menu_item = new GLib.MenuItem (_("Alphabetize"), Scratch.MainWindow.ACTION_PREFIX
- + Scratch.MainWindow.ACTION_ORDER_FOLDERS);
+ var order_projects_menu_item = new Gtk.ModelButton () {
+ text = _("Alphabetize"),
+ action_name = Scratch.MainWindow.ACTION_PREFIX + Scratch.MainWindow.ACTION_ORDER_FOLDERS
+ };
- var project_menu = new GLib.Menu ();
- project_menu.append_item (collapse_all_menu_item);
- project_menu.append_item (order_projects_menu_item);
- project_menu_model = project_menu;
+ project_menu = new Gtk.Box (VERTICAL, 0);
+ project_menu.add (collapse_all_menu_item);
+ project_menu.add (order_projects_menu_item);
+ project_menu.show_all ();
+ var project_menu_model = new Gtk.Popover (null);
+ project_menu_model.add (project_menu);
- var label = new Gtk.Label ( _("Manage project folders…")) {
- halign = START
- };
var project_menu_button = new Gtk.MenuButton () {
hexpand = true,
- use_popover = false,
- menu_model = project_menu_model,
- child = label
+ halign = START,
+ popover = project_menu_model,
+ label = _("Manage project folders…")
};
actionbar.pack_start (project_menu_button);
@@ -131,6 +136,31 @@ public class Code.Sidebar : Gtk.Grid {
Gtk.TargetEntry uris = {"text/uri-list", 0, TargetType.URI_LIST};
Gtk.drag_dest_set (this, Gtk.DestDefaults.ALL, {uris}, Gdk.DragAction.COPY);
drag_data_received.connect (drag_received);
+
+ project_menu_map = new HashTable (str_hash, str_equal);
+ }
+
+ public void add_project_menu_widget (string id, Gtk.Widget widget) {
+ if (project_menu_map.size () == 0) {
+ project_menu_separator = new Gtk.Separator (HORIZONTAL);
+ project_menu.add (project_menu_separator);
+ }
+
+ project_menu.add (widget);
+ project_menu_map.@set (id, widget);
+ project_menu.show_all ();
+ }
+
+ public void remove_project_menu_widget (string id) {
+ var item = project_menu_map.take (id);
+ if (item != null) {
+ item.destroy ();
+ }
+
+ if (project_menu_map.size () == 0) {
+ project_menu_separator.destroy ();
+ }
+
}
private void drag_received (Gtk.Widget w,