diff --git a/src/SymbolPane/SymbolOutline.vala b/src/SymbolPane/SymbolOutline.vala index 1e5fcce80b..963803249b 100644 --- a/src/SymbolPane/SymbolOutline.vala +++ b/src/SymbolPane/SymbolOutline.vala @@ -1,19 +1,7 @@ -/*- - * Copyright (c) 2013-2025 elementary LLC. (https://elementary.io) - * Copyright (C) 2013 Tom Beckmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . +/* + * SPDX-License-Identifier: LGPL-3.0-or-later + * SPDX-FileCopyrightText: 2013-2025 elementary Inc. (https://elementary.io) + * 2013 Tom Beckmann */ public enum Scratch.Services.SymbolType { @@ -64,21 +52,13 @@ public interface Scratch.Services.SymbolItem : Code.Widgets.SourceList.Expandabl } public class Scratch.Services.SymbolOutline : Gtk.Box { - protected static SymbolType[] filters; //Initialized by derived classes const string ACTION_GROUP = "symbol"; 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; } - - protected Gee.HashMap checks; - protected Gtk.SearchEntry search_entry; - protected Code.Widgets.SourceList store; - protected Code.Widgets.SourceList.ExpandableItem root; - protected Gtk.CssProvider source_list_style_provider; public Gtk.Widget get_widget () { return this; } public bool tool_box_sensitive { set { @@ -87,36 +67,21 @@ public class Scratch.Services.SymbolOutline : Gtk.Box { } } + protected static SymbolType[] filters; //Initialized by derived classes + protected Gee.HashMap checks; + protected Gtk.SearchEntry search_entry; + protected Code.Widgets.SourceList store; + protected Code.Widgets.SourceList.ExpandableItem root; + protected Gtk.CssProvider source_list_style_provider; 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) {} private Gtk.MenuButton filter_button; + private uint refilter_timeout_id = 0; + private bool delay_refilter = false; private Gtk.Spinner spinner; + private uint show_spinner_timeout_id = 0; private Gtk.Stack stack; + private SimpleActionGroup symbol_action_group; construct { symbol_action_group = new SimpleActionGroup (); @@ -192,61 +157,30 @@ public class Scratch.Services.SymbolOutline : Gtk.Box { }); } - private void add_filter_menuitem (Menu menu, SymbolType filter) { - var filter_action = new SimpleAction.stateful ( - ACTION_TOGGLE + ((uint)filter).to_string (), - null, - new Variant.boolean (true) - ); - - checks[filter] = filter_action; - filter_action.activate.connect (action_toggle_filter); - symbol_action_group.add_action (filter_action); - - var filter_item = new MenuItem ( - filter.to_string (), - ACTION_PREFIX + filter_action.get_name () - ); + public virtual void parse_symbols () {} + public virtual void add_tooltips (Code.Widgets.SourceList.ExpandableItem root) {} - menu.append_item (filter_item); + protected void before_parse () { + tool_box_sensitive = true; + took_too_long = false; + show_spinner_timeout_id = Timeout.add_once (SPINNER_DELAY_MSEC, () => { + show_spinner_timeout_id = 0; + stack.visible_child = spinner; + spinner.start (); + }); } - protected bool filter_func (Object item) { - if (!(item is SymbolItem)) { - return true; - } - - var symbol_type = ((SymbolItem)item).symbol_type; - if (symbol_type == SymbolType.NAMESPACE) { - return true; - } - - if (checks[symbol_type] == null) { - symbol_type = SymbolType.OTHER; - } - - var filter_action = checks[symbol_type]; - - if (!filter_action.get_state ().get_boolean ()) { - return false; - } - - // Do not exclude text search misses on Item with children as may - // hide hits on its children - if (item is Code.Widgets.SourceList.ExpandableItem) { - var expandable = (Code.Widgets.SourceList.ExpandableItem)item; - if (expandable.n_children > 0) { - return true; - } - - return ((SymbolItem)item).name.contains (search_entry.text); + protected void after_parse () { + if (show_spinner_timeout_id > 0) { + Source.remove (show_spinner_timeout_id); + show_spinner_timeout_id = 0; } - return true; + spinner.stop (); + stack.visible_child = filter_button; + tool_box_sensitive = !took_too_long; } - uint refilter_timeout_id = 0; - bool delay_refilter = false; protected void schedule_refilter () { // Ensure a refilter happens at least 500mS later if not already // delayed. @@ -300,15 +234,67 @@ public class Scratch.Services.SymbolOutline : Gtk.Box { } } + protected bool filter_func (Object item) { + if (!(item is SymbolItem)) { + return true; + } + + var symbol_type = ((SymbolItem)item).symbol_type; + if (symbol_type == SymbolType.NAMESPACE) { + return true; + } + + if (checks[symbol_type] == null) { + symbol_type = SymbolType.OTHER; + } + + var filter_action = checks[symbol_type]; + + if (!filter_action.get_state ().get_boolean ()) { + return false; + } + + // Do not exclude text search misses on Item with children as may + // hide hits on its children + if (item is Code.Widgets.SourceList.ExpandableItem) { + var expandable = (Code.Widgets.SourceList.ExpandableItem)item; + if (expandable.n_children > 0) { + return true; + } + + return ((SymbolItem)item).name.contains (search_entry.text); + } + + return true; + } + + private void add_filter_menuitem (Menu menu, SymbolType filter) { + var filter_action = new SimpleAction.stateful ( + ACTION_TOGGLE + ((uint)filter).to_string (), + null, + new Variant.boolean (true) + ); + + checks[filter] = filter_action; + filter_action.activate.connect (action_toggle_filter); + symbol_action_group.add_action (filter_action); + + var filter_item = new MenuItem ( + filter.to_string (), + ACTION_PREFIX + filter_action.get_name () + ); + + menu.append_item (filter_item); + } + private void action_select_filters (SimpleAction action, Variant? param) { foreach (var filter_action in checks.values) { filter_action.set_state (new Variant ("b", param.get_boolean ())); } schedule_refilter (); // Keep menu open - Idle.add (() => { + Idle.add_once (() => { filter_button.set_active (true); - return Source.REMOVE; }); }