diff --git a/src/SymbolPane/C/CtagsSymbolOutline.vala b/src/SymbolPane/C/CtagsSymbolOutline.vala index 97c06f0d97..92b540cdef 100644 --- a/src/SymbolPane/C/CtagsSymbolOutline.vala +++ b/src/SymbolPane/C/CtagsSymbolOutline.vala @@ -55,6 +55,7 @@ public class Scratch.Services.CtagsSymbolOutline : Scratch.Services.SymbolOutlin } public override void parse_symbols () { + before_parse (); if (current_subprocess != null) current_subprocess.force_exit (); @@ -64,9 +65,12 @@ public class Scratch.Services.CtagsSymbolOutline : Scratch.Services.SymbolOutlin "ctags", "-f", "-", "--format=2", "--excmd=n", "--fields=nstK", "--extra=", "--sort=no", doc.file.get_path () ); - parse_output.begin (current_subprocess); + parse_output.begin (current_subprocess, (obj, res) => { + after_parse (); + }); } catch (GLib.Error e) { critical (e.message); + after_parse (); } } diff --git a/src/SymbolPane/SymbolOutline.vala b/src/SymbolPane/SymbolOutline.vala index 3752219e9f..cabd32bab2 100644 --- a/src/SymbolPane/SymbolOutline.vala +++ b/src/SymbolPane/SymbolOutline.vala @@ -69,6 +69,7 @@ public class Scratch.Services.SymbolOutline : Gtk.Box { const string ACTION_PREFIX = ACTION_GROUP + "."; const string ACTION_SELECT = "action-select"; const string ACTION_TOGGLE = "toggle-"; + const uint SPINNER_DELAY_MSEC = 300; SimpleActionGroup symbol_action_group; public Scratch.Services.Document doc { get; construct; } @@ -86,10 +87,36 @@ public class Scratch.Services.SymbolOutline : Gtk.Box { } } + protected bool took_too_long; + private uint show_spinner_timeout_id = 0; + protected void before_parse () { + tool_box_sensitive = true; + took_too_long = false; + show_spinner_timeout_id = Timeout.add (SPINNER_DELAY_MSEC, () => { + show_spinner_timeout_id = 0; + stack.visible_child = spinner; + spinner.start (); + return Source.REMOVE; + }); + } + + protected void after_parse () { + if (show_spinner_timeout_id > 0) { + Source.remove (show_spinner_timeout_id); + show_spinner_timeout_id = 0; + } + + spinner.stop (); + stack.visible_child = filter_button; + tool_box_sensitive = !took_too_long; + } + public virtual void parse_symbols () {} public virtual void add_tooltips (Code.Widgets.SourceList.ExpandableItem root) {} - Gtk.MenuButton filter_button; + private Gtk.MenuButton filter_button; + private Gtk.Spinner spinner; + private Gtk.Stack stack; construct { symbol_action_group = new SimpleActionGroup (); @@ -145,9 +172,15 @@ public class Scratch.Services.SymbolOutline : Gtk.Box { filter_button.menu_model = top_model; + spinner = new Gtk.Spinner (); + stack = new Gtk.Stack (); + stack.add (filter_button); + stack.add (spinner); + stack.visible_child = filter_button; + var tool_box = new Gtk.Box (HORIZONTAL, 3); tool_box.add (search_entry); - tool_box.add (filter_button); + tool_box.add (stack); add (tool_box); add (store); set_up_css (); diff --git a/src/SymbolPane/Vala/ValaSymbolOutline.vala b/src/SymbolPane/Vala/ValaSymbolOutline.vala index 5d27e74cd3..63e977c1a3 100644 --- a/src/SymbolPane/Vala/ValaSymbolOutline.vala +++ b/src/SymbolPane/Vala/ValaSymbolOutline.vala @@ -74,7 +74,7 @@ public class Scratch.Services.ValaSymbolOutline : Scratch.Services.SymbolOutline private uint parse_timeout_id = 0; public override void parse_symbols () { - tool_box_sensitive = true; + before_parse (); var context = new Vala.CodeContext (); #if VALA_0_50 context.set_target_profile (Vala.Profile.GOBJECT, false); @@ -95,7 +95,6 @@ public class Scratch.Services.ValaSymbolOutline : Scratch.Services.SymbolOutline resolver.resolve (context); Vala.CodeContext.pop (); - bool took_too_long = false; parse_timeout_id = Timeout.add_full (Priority.LOW, PARSE_TIME_MAX_MSEC, () => { parse_timeout_id = 0; took_too_long = true; @@ -126,8 +125,6 @@ public class Scratch.Services.ValaSymbolOutline : Scratch.Services.SymbolOutline }; store.root.add (warning_item); - tool_box_sensitive = false; - } else { store.root.add (new_root); } @@ -135,12 +132,13 @@ public class Scratch.Services.ValaSymbolOutline : Scratch.Services.SymbolOutline store.root.expand_all (); add_tooltips (store.root); store.vadjustment.set_value (adjustment_value); - return false; + return Source.REMOVE; }); } else { destroy_all_children (new_root); } + after_parse (); return null; }); }