From 9d698f85140419477d6ed88089b36b857ed2e4b8 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Thu, 16 Jan 2025 17:28:56 +0000 Subject: [PATCH 1/8] Do not replace search term with doc selection unless action-fetch activated --- src/MainWindow.vala | 24 ++++++++++++------------ src/Widgets/SearchBar.vala | 14 -------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 34fe7d93d..85b0e0e1e 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -1240,6 +1240,18 @@ namespace Scratch { } private void set_search_text () { + var current_doc = get_current_document (); + // This is also called when all documents are closed. + if (current_doc != null) { + var selected_text = current_doc.get_selected_text (false); + if (selected_text != "" && selected_text.length < MAX_SEARCH_TEXT_LENGTH) { + current_search_term = selected_text.split ("\n", 2)[0]; + search_bar.search_entry.text = current_search_term; + } + + search_bar.search_entry.grab_focus (); /* causes loss of document selection */ + } + if (current_search_term != "") { search_bar.search_entry.text = current_search_term; search_bar.search_entry.grab_focus (); @@ -1248,18 +1260,6 @@ namespace Scratch { // Always search on what is showing in search entry current_search_term = search_bar.search_entry.text; search_bar.search_entry.grab_focus (); - } else { - var current_doc = get_current_document (); - // This is also called when all documents are closed. - if (current_doc != null) { - var selected_text = current_doc.get_selected_text (false); - if (selected_text != "" && selected_text.length < MAX_SEARCH_TEXT_LENGTH) { - current_search_term = selected_text.split ("\n", 2)[0]; - search_bar.search_entry.text = current_search_term; - } - - search_bar.search_entry.grab_focus (); /* causes loss of document selection */ - } } if (current_search_term != "") { diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 5f43f0015..6e752bbca 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -233,11 +233,9 @@ namespace Scratch.Widgets { return; } else if (this.text_buffer != null) { this.text_buffer.changed.disconnect (on_text_buffer_changed); - this.text_view.selection_changed.disconnect (on_selection_changed); } this.text_view = text_view; - this.text_view.selection_changed.connect (on_selection_changed); this.text_buffer = text_view.get_buffer (); this.text_buffer.changed.connect (on_text_buffer_changed); this.search_context = new Gtk.SourceSearchContext (text_buffer as Gtk.SourceBuffer, null); @@ -251,20 +249,8 @@ namespace Scratch.Widgets { update_search_widgets (); } - private void on_selection_changed () { - var selected_text = text_view.get_selected_text (); - bool clear_required; - if (search_context.settings.case_sensitive) { - clear_required = selected_text != search_entry.text; - } else { - clear_required = selected_text.down () != search_entry.text.down (); - } - if (clear_required) { - search_entry.text = ""; - } - } private void on_replace_entry_activate () { if (text_buffer == null) { From 0be7a000f6d99181e1227a2031242498b2475b80 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 21 Jan 2025 12:49:05 +0000 Subject: [PATCH 2/8] Prioritise non empty current search entry for when setting search text --- src/MainWindow.vala | 14 +++++++------- src/Widgets/SearchBar.vala | 6 +----- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 85b0e0e1e..8b6d1e27b 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -116,7 +116,7 @@ namespace Scratch { private Services.GitManager git_manager; private const ActionEntry[] ACTION_ENTRIES = { - { ACTION_FIND, action_fetch, "s" }, + { ACTION_FIND, action_fetch}, { ACTION_FIND_NEXT, action_find_next }, { ACTION_FIND_PREVIOUS, action_find_previous }, { ACTION_FIND_GLOBAL, action_find_global, "s" }, @@ -183,7 +183,7 @@ namespace Scratch { } static construct { - action_accelerators.set (ACTION_FIND + "::", "f"); + action_accelerators.set (ACTION_FIND, "f"); action_accelerators.set (ACTION_FIND_NEXT, "g"); action_accelerators.set (ACTION_FIND_PREVIOUS, "g"); action_accelerators.set (ACTION_FIND_GLOBAL + "::", "f"); @@ -446,7 +446,8 @@ namespace Scratch { search_bar.search_entry.text = ""; search_bar.highlight_none (); }); - search_bar.search_empty.connect (() => { + search_bar.search_changed.connect ((search_term) => { + current_search_term = search_term; folder_manager_view.clear_badges (); }); @@ -1162,8 +1163,7 @@ namespace Scratch { /** Not a toggle action - linked to keyboard short cut (Ctrl-f). **/ private string current_search_term = ""; - private void action_fetch (SimpleAction action, Variant? param) { - current_search_term = param != null ? param.get_string () : ""; + private void action_fetch () { if (!search_revealer.child_revealed) { var show_find_action = Utils.action_from_group (ACTION_SHOW_FIND, actions); if (show_find_action.enabled) { @@ -1178,7 +1178,7 @@ namespace Scratch { } private void action_show_replace (SimpleAction action) { - action_fetch (action, null); + action_fetch (); // May have to wait for the search bar to be revealed before we can grab focus if (search_revealer.child_revealed) { search_bar.replace_entry.grab_focus (); @@ -1242,7 +1242,7 @@ namespace Scratch { private void set_search_text () { var current_doc = get_current_document (); // This is also called when all documents are closed. - if (current_doc != null) { + if (current_search_term == "" && current_doc != null) { var selected_text = current_doc.get_selected_text (false); if (selected_text != "" && selected_text.length < MAX_SEARCH_TEXT_LENGTH) { current_search_term = selected_text.split ("\n", 2)[0]; diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 6e752bbca..f170b1f3a 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -52,7 +52,7 @@ namespace Scratch.Widgets { private Gtk.TextBuffer? text_buffer = null; public Gtk.SourceSearchContext? search_context { get; private set; default = null; } - public signal void search_empty (); + public signal void search_changed (string search_term); private uint update_search_label_timeout_id = 0; @@ -320,10 +320,6 @@ namespace Scratch.Widgets { search_context.settings.regex_enabled = regex_search_button.active; update_search_widgets (); - - if (search_entry.text == "") { - search_empty (); - } } private bool on_search_entry_focused_in (Gdk.EventFocus event) { From 854003d6d5295a21ff25a0a75a73c9fcb8e18a8b Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Fri, 24 Jan 2025 19:19:24 +0000 Subject: [PATCH 3/8] Make SearchBar more self-contained; simplify; cleanup --- .../highlight-word-selection.vala | 8 +- src/MainWindow.vala | 143 +++++++----------- src/Widgets/HeaderBar.vala | 2 +- src/Widgets/SearchBar.vala | 111 +++++++++----- 4 files changed, 130 insertions(+), 134 deletions(-) diff --git a/plugins/highlight-word-selection/highlight-word-selection.vala b/plugins/highlight-word-selection/highlight-word-selection.vala index 5896b5d43..dad2f0465 100644 --- a/plugins/highlight-word-selection/highlight-word-selection.vala +++ b/plugins/highlight-word-selection/highlight-word-selection.vala @@ -50,12 +50,8 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A }); } - public void on_selection_changed (ref Gtk.TextIter start, ref Gtk.TextIter end) { - var window_search_context = main_window != null ? main_window.search_bar.search_context : null; - - if (window_search_context == null || - window_search_context.settings.search_text == "" || - window_search_context.get_occurrences_count () == 0) { + public void on_selection_changed (ref Gtk.TextIter start, ref Gtk.TextIter end) requires (main_window != null) { + if (!main_window.has_successful_search ()) { // Perform plugin selection when there is no ongoing and successful search current_search_context = new Gtk.SourceSearchContext ( (Gtk.SourceBuffer)current_source.buffer, diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 8b6d1e27b..852a5b8e3 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -32,7 +32,6 @@ namespace Scratch { // Widgets public Scratch.HeaderBar toolbar; - private Gtk.Revealer search_revealer; public Scratch.Widgets.SearchBar search_bar; private Code.WelcomeView welcome_view; private Code.Terminal terminal; @@ -78,7 +77,6 @@ namespace Scratch { public const string ACTION_REVERT = "action-revert"; public const string ACTION_SAVE = "action-save"; public const string ACTION_SAVE_AS = "action-save-as"; - public const string ACTION_SHOW_FIND = "action-show-find"; public const string ACTION_TEMPLATES = "action-templates"; public const string ACTION_SHOW_REPLACE = "action-show-replace"; public const string ACTION_TO_LOWER_CASE = "action-to-lower-case"; @@ -90,6 +88,7 @@ namespace Scratch { public const string ACTION_ZOOM_IN = "action-zoom-in"; public const string ACTION_ZOOM_OUT = "action-zoom-out"; public const string ACTION_TOGGLE_COMMENT = "action-toggle-comment"; + public const string ACTION_TOGGLE_SHOW_FIND = "action-toggle_show-find"; public const string ACTION_TOGGLE_SIDEBAR = "action-toggle-sidebar"; public const string ACTION_TOGGLE_OUTLINE = "action-toggle-outline"; public const string ACTION_TOGGLE_TERMINAL = "action-toggle-terminal"; @@ -116,7 +115,7 @@ namespace Scratch { private Services.GitManager git_manager; private const ActionEntry[] ACTION_ENTRIES = { - { ACTION_FIND, action_fetch}, + { ACTION_FIND, action_find}, { ACTION_FIND_NEXT, action_find_next }, { ACTION_FIND_PREVIOUS, action_find_previous }, { ACTION_FIND_GLOBAL, action_find_global, "s" }, @@ -128,7 +127,7 @@ namespace Scratch { { ACTION_REVERT, action_revert }, { ACTION_SAVE, action_save }, { ACTION_SAVE_AS, action_save_as }, - { ACTION_SHOW_FIND, action_show_fetch, null, "false" }, + { ACTION_TOGGLE_SHOW_FIND, action_toggle_show_find, null, "false" }, { ACTION_TEMPLATES, action_templates }, { ACTION_GO_TO, action_go_to }, { ACTION_SORT_LINES, action_sort_lines }, @@ -370,7 +369,7 @@ namespace Scratch { private void update_toolbar_button (string name, bool new_state) { switch (name) { - case ACTION_SHOW_FIND: + case ACTION_TOGGLE_SHOW_FIND: if (new_state) { toolbar.find_button.tooltip_markup = Granite.markup_accel_tooltip ( {"Escape"}, @@ -383,7 +382,7 @@ namespace Scratch { ); } - search_revealer.set_reveal_child (new_state); + search_bar.reveal (new_state); break; case ACTION_TOGGLE_SIDEBAR: @@ -436,21 +435,6 @@ namespace Scratch { // SearchBar search_bar = new Scratch.Widgets.SearchBar (this); - search_revealer = new Gtk.Revealer (); - search_revealer.add (search_bar); - - search_bar.map.connect_after ((w) => { /* signalled when reveal child */ - set_search_text (); - }); - search_bar.search_entry.unmap.connect_after (() => { /* signalled when reveal child */ - search_bar.search_entry.text = ""; - search_bar.highlight_none (); - }); - search_bar.search_changed.connect ((search_term) => { - current_search_term = search_term; - folder_manager_view.clear_badges (); - }); - welcome_view = new Code.WelcomeView (this); document_view = new Scratch.Widgets.DocumentView (this); // Handle Drag-and-drop for files functionality on welcome screen @@ -520,7 +504,7 @@ namespace Scratch { var view_grid = new Gtk.Grid () { orientation = Gtk.Orientation.VERTICAL }; - view_grid.add (search_revealer); + view_grid.add (search_bar); view_grid.add (document_view); content_stack = new Gtk.Stack () { @@ -559,8 +543,6 @@ namespace Scratch { size_group.add_widget (sidebar.headerbar); size_group.add_widget (toolbar); - search_revealer.set_reveal_child (false); - realize.connect (() => { Scratch.saved_state.bind ("sidebar-visible", sidebar, "visible", SettingsBindFlags.DEFAULT); Scratch.saved_state.bind ("outline-visible", document_view , "outline_visible", SettingsBindFlags.DEFAULT); @@ -705,13 +687,12 @@ namespace Scratch { }); } - // private bool on_key_pressed (Gdk.EventKey event) { private bool on_key_pressed (uint keyval, uint keycode, Gdk.ModifierType state) { switch (Gdk.keyval_name (keyval)) { case "Escape": - if (search_revealer.get_child_revealed ()) { - var fetch_action = Utils.action_from_group (ACTION_SHOW_FIND, actions); - fetch_action.set_state (false); + if (search_bar.is_revealed) { + var action = Utils.action_from_group (ACTION_TOGGLE_SHOW_FIND, actions); + action.set_state (false); document_view.current_document.source_view.grab_focus (); } @@ -730,7 +711,7 @@ namespace Scratch { // Set sensitive property for 'delicate' Widgets/GtkActions while private void set_widgets_sensitive (bool val) { // SearchManager's stuffs - Utils.action_from_group (ACTION_SHOW_FIND, actions).set_enabled (val); + Utils.action_from_group (ACTION_TOGGLE_SHOW_FIND, actions).set_enabled (val); Utils.action_from_group (ACTION_GO_TO, actions).set_enabled (val); Utils.action_from_group (ACTION_SHOW_REPLACE, actions).set_enabled (val); // Toolbar Actions @@ -753,6 +734,15 @@ namespace Scratch { return document_view.current_document; } + public string get_selected_text () { + var doc = get_current_document (); + return doc != null ? doc.get_selected_text (false) : ""; + } + + public bool has_successful_search () { + return search_bar.search_occurrences > 0; + } + public void open_folder (File folder) { var foldermanager_file = new FolderManager.File (folder.get_path ()); folder_manager_view.open_folder (foldermanager_file); @@ -1162,31 +1152,36 @@ namespace Scratch { } /** Not a toggle action - linked to keyboard short cut (Ctrl-f). **/ - private string current_search_term = ""; - private void action_fetch () { - if (!search_revealer.child_revealed) { - var show_find_action = Utils.action_from_group (ACTION_SHOW_FIND, actions); + private void action_find () { + if (!search_bar.is_revealed) { + var show_find_action = Utils.action_from_group (ACTION_TOGGLE_SHOW_FIND, actions); if (show_find_action.enabled) { /* Toggling the fetch action causes this function to be called again but the search_revealer child * is still not revealed so nothing more happens. We use the map signal on the search entry * to set it up once it has been revealed. */ show_find_action.set_state (true); } - } else { - set_search_text (); + } else if (!search_bar.is_focused) { + var selected_text = get_selected_text (); + if (selected_text != "") { + search_bar.set_search_entry_text (selected_text); + } } + + search_bar.search (); } private void action_show_replace (SimpleAction action) { - action_fetch (); + action_find (); // May have to wait for the search bar to be revealed before we can grab focus - if (search_revealer.child_revealed) { - search_bar.replace_entry.grab_focus (); + + if (search_bar.is_revealed) { + search_bar.focus_replace_entry (); } else { - ulong map_handler = 0; - map_handler = search_bar.map.connect_after (() => { - search_bar.replace_entry.grab_focus (); - search_bar.disconnect (map_handler); + search_bar.reveal (true); + Idle.add (() => { + search_bar.focus_replace_entry (); + return Source.REMOVE; }); } } @@ -1201,27 +1196,18 @@ namespace Scratch { private void action_find_global (SimpleAction action, Variant? param) { var current_doc = get_current_document (); - string selected_text = ""; - if (current_doc != null) { - selected_text = current_doc.get_selected_text (false); - } + var selected_text = current_doc != null ? current_doc.get_selected_text (false) : ""; + selected_text = selected_text.split ("\n", 2)[0]; - if (selected_text != "") { - selected_text = selected_text.split ("\n", 2)[0]; - } - // If search entry focused use its text for search term, else use selected text - var term = search_bar.search_entry.has_focus ? - search_bar.search_entry.text : selected_text; - - // If no focused selected text fallback to search entry text if visible - if (term == "" && - !search_bar.search_entry.has_focus && - search_revealer.reveal_child) { - - term = search_bar.search_entry.text; + var search_term = ""; + if (search_bar.is_focused || selected_text == "") { + search_term = search_bar.entry_text; + } else { + search_term = selected_text; } - folder_manager_view.search_global (get_target_path_for_actions (param), term); + folder_manager_view.search_global (get_target_path_for_actions (param), search_term); + search_bar.set_search_entry_text (search_term); } private void update_find_actions () { @@ -1229,7 +1215,7 @@ namespace Scratch { Idle.add (() => { var is_current_doc = get_current_document () != null; Utils.action_from_group (ACTION_FIND, actions).set_enabled (is_current_doc); - Utils.action_from_group (ACTION_SHOW_FIND, actions).set_enabled (is_current_doc); + Utils.action_from_group (ACTION_TOGGLE_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); @@ -1239,38 +1225,11 @@ namespace Scratch { }); } - private void set_search_text () { - var current_doc = get_current_document (); - // This is also called when all documents are closed. - if (current_search_term == "" && current_doc != null) { - var selected_text = current_doc.get_selected_text (false); - if (selected_text != "" && selected_text.length < MAX_SEARCH_TEXT_LENGTH) { - current_search_term = selected_text.split ("\n", 2)[0]; - search_bar.search_entry.text = current_search_term; - } - - search_bar.search_entry.grab_focus (); /* causes loss of document selection */ - } - - if (current_search_term != "") { - search_bar.search_entry.text = current_search_term; - search_bar.search_entry.grab_focus (); - search_bar.search_next (); - } else if (search_bar.search_entry.text != "") { - // Always search on what is showing in search entry - current_search_term = search_bar.search_entry.text; - search_bar.search_entry.grab_focus (); - } - - if (current_search_term != "") { - search_bar.search_next (); /* this selects the next match (if any) */ - } - } - /** Toggle action - linked to toolbar togglebutton. **/ - private void action_show_fetch () { - var fetch_action = Utils.action_from_group (ACTION_SHOW_FIND, actions); - fetch_action.set_state (!fetch_action.get_state ().get_boolean ()); + private void action_toggle_show_find () { + var action = Utils.action_from_group (ACTION_TOGGLE_SHOW_FIND, actions); + action.set_state (!action.get_state ().get_boolean ()); + search_bar.reveal (action.get_state ().get_boolean ()); } private void action_go_to () { diff --git a/src/Widgets/HeaderBar.vala b/src/Widgets/HeaderBar.vala index 791361442..55e3ce2f0 100644 --- a/src/Widgets/HeaderBar.vala +++ b/src/Widgets/HeaderBar.vala @@ -114,7 +114,7 @@ public class Scratch.HeaderBar : Hdy.HeaderBar { font_size_box.add (zoom_in_button); find_button = new Gtk.ToggleButton () { - action_name = MainWindow.ACTION_PREFIX + MainWindow.ACTION_SHOW_FIND, + action_name = MainWindow.ACTION_PREFIX + MainWindow.ACTION_TOGGLE_SHOW_FIND, image = new Gtk.Image.from_icon_name ("edit-find-on-page-symbolic", Gtk.IconSize.MENU) }; find_button.tooltip_markup = Granite.markup_accel_tooltip ( diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index f170b1f3a..a0d897bfe 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -20,7 +20,7 @@ */ namespace Scratch.Widgets { - public class SearchBar : Gtk.FlowBox { + public class SearchBar : Gtk.Box { //TODO In Gtk4 use a BinLayout Widget enum CaseSensitiveMode { NEVER, MIXED, @@ -28,6 +28,7 @@ namespace Scratch.Widgets { } public weak MainWindow window { get; construct; } + private Gtk.Button tool_arrow_up; private Gtk.Button tool_arrow_down; @@ -40,32 +41,53 @@ namespace Scratch.Widgets { private Gtk.ComboBoxText case_sensitive_search_button; private Granite.SwitchModelButton regex_search_button; private Granite.SwitchModelButton whole_word_search_button; - public Gtk.SearchEntry search_entry; - public Gtk.SearchEntry replace_entry; - + private Gtk.SearchEntry search_entry; + private Gtk.SearchEntry replace_entry; private Gtk.Label search_occurence_count_label; - private Gtk.Button replace_tool_button; private Gtk.Button replace_all_tool_button; - private Scratch.Widgets.SourceView? text_view = null; private Gtk.TextBuffer? text_buffer = null; - public Gtk.SourceSearchContext? search_context { get; private set; default = null; } + private Gtk.SourceSearchContext? search_context; + private uint update_search_label_timeout_id = 0; + private Gtk.Revealer revealer; - public signal void search_changed (string search_term); + public bool is_focused { + get { + return search_entry.has_focus || replace_entry.has_focus; + } + } - private uint update_search_label_timeout_id = 0; + public bool is_revealed { + get { + return revealer.child_revealed; + } + } + + public string entry_text { + get { + return search_entry.text; + } + } + + public uint search_occurrences { + get { + if (search_context == null || + search_context.settings.search_text == "") { + + return 0; + } else { + return search_context.get_occurrences_count (); + } + } + } - /** - * Create a new SearchBar widget. - * - * following actions : Fetch, ShowGoTo, ShowReplace, or null. - **/ public SearchBar (MainWindow window) { Object (window: window); } construct { + this.orientation = HORIZONTAL; search_entry = new Gtk.SearchEntry () { hexpand = true, placeholder_text = _("Find") @@ -137,10 +159,10 @@ namespace Scratch.Widgets { }; search_menubutton.add (search_buttonbox); - cycle_search_button.toggled.connect (on_search_entry_text_changed); - case_sensitive_search_button.changed.connect (on_search_entry_text_changed); - whole_word_search_button.toggled.connect (on_search_entry_text_changed); - regex_search_button.toggled.connect (on_search_entry_text_changed); + cycle_search_button.toggled.connect (on_search_parameters_changed); + case_sensitive_search_button.changed.connect (on_search_parameters_changed); + whole_word_search_button.toggled.connect (on_search_parameters_changed); + regex_search_button.toggled.connect (on_search_parameters_changed); Scratch.settings.bind ("cyclic-search", cycle_search_button, "active", SettingsBindFlags.DEFAULT); Scratch.settings.bind ("wholeword-search", whole_word_search_button, "active", SettingsBindFlags.DEFAULT); @@ -190,10 +212,9 @@ namespace Scratch.Widgets { replace_flow_box_child.add (replace_grid); // Connecting to some signals - search_entry.changed.connect (on_search_entry_text_changed); + search_entry.changed.connect (on_search_parameters_changed); search_entry.key_press_event.connect (on_search_entry_key_press); search_entry.focus_in_event.connect (on_search_entry_focused_in); - search_entry.search_changed.connect (update_search_widgets); search_entry.icon_release.connect ((p0, p1) => { if (p0 == Gtk.EntryIconPosition.PRIMARY) { search_next (); @@ -209,13 +230,21 @@ namespace Scratch.Widgets { entry_context.set_path (entry_path); entry_context.add_class ("entry"); - selection_mode = Gtk.SelectionMode.NONE; - column_spacing = 6; - max_children_per_line = 2; - get_style_context ().add_class ("search-bar"); - add (search_flow_box_child); - add (replace_flow_box_child); + var flowbox = new Gtk.FlowBox () { + selection_mode = Gtk.SelectionMode.NONE, + column_spacing = 6, + max_children_per_line = 2 + }; + flowbox.get_style_context ().add_class ("search-bar"); + flowbox.add (search_flow_box_child); + flowbox.add (replace_flow_box_child); + revealer = new Gtk.Revealer () { + child = flowbox, + reveal_child = false + }; + + add (revealer); update_search_widgets (); } @@ -249,9 +278,6 @@ namespace Scratch.Widgets { update_search_widgets (); } - - - private void on_replace_entry_activate () { if (text_buffer == null) { warning ("No valid buffer to replace"); @@ -293,12 +319,8 @@ namespace Scratch.Widgets { this.window.get_current_document ().toggle_changed_handlers (true); } - private void on_search_entry_text_changed () { - if (search_context == null) { // This can happen during start up - debug ("search entry changed with null context"); - return; - } - + // Called when one of the settings buttons or the search term changes + private void on_search_parameters_changed () requires (search_context != null) { var search_string = search_entry.text; search_context.settings.search_text = search_string; var case_mode = (CaseSensitiveMode)(case_sensitive_search_button.active); @@ -459,6 +481,25 @@ namespace Scratch.Widgets { } } + public void focus_search_entry () { + search_entry.grab_focus (); + } + + public void focus_replace_entry () { + replace_entry.grab_focus (); + } + + public void reveal (bool visible) { + revealer.reveal_child = visible; + if (!visible) { + search_entry.text = ""; + } + } + + public void set_search_entry_text (string text) { + search_entry.text = text; + } + private bool on_search_entry_key_press (Gdk.EventKey event) { /* We don't need to perform search if there is nothing to search... */ if (search_entry.text == "") { From 4a637ce62543d5172c9d93e06484ace79e51583f Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 25 Jan 2025 17:37:02 +0000 Subject: [PATCH 4/8] Focus search after showing searchbar --- src/MainWindow.vala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 852a5b8e3..15be67be0 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -1156,10 +1156,7 @@ namespace Scratch { if (!search_bar.is_revealed) { var show_find_action = Utils.action_from_group (ACTION_TOGGLE_SHOW_FIND, actions); if (show_find_action.enabled) { - /* Toggling the fetch action causes this function to be called again but the search_revealer child - * is still not revealed so nothing more happens. We use the map signal on the search entry - * to set it up once it has been revealed. */ - show_find_action.set_state (true); + show_find_action.activate (new Variant ("b", true)); } } else if (!search_bar.is_focused) { var selected_text = get_selected_text (); @@ -1228,8 +1225,12 @@ namespace Scratch { /** Toggle action - linked to toolbar togglebutton. **/ private void action_toggle_show_find () { var action = Utils.action_from_group (ACTION_TOGGLE_SHOW_FIND, actions); - action.set_state (!action.get_state ().get_boolean ()); - search_bar.reveal (action.get_state ().get_boolean ()); + var to_show = !action.get_state ().get_boolean (); + action.set_state (to_show); + search_bar.reveal (to_show); + if (to_show) { + search_bar.focus_search_entry (); + } } private void action_go_to () { From 0c72a9428c770126b757816189104a030d0013ea Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Sat, 25 Jan 2025 18:21:34 +0000 Subject: [PATCH 5/8] Ensure searchbar visible and shows expected search term on searches --- src/MainWindow.vala | 32 ++++++++++++++++++-------------- src/Widgets/SearchBar.vala | 15 +++++++++++---- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 15be67be0..ec35bd80b 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -734,9 +734,12 @@ namespace Scratch { return document_view.current_document; } - public string get_selected_text () { + // If selected text covers more than one line return just the first. + // Returns "" if no selection + public string get_selected_text_for_search () { var doc = get_current_document (); - return doc != null ? doc.get_selected_text (false) : ""; + var text = doc != null ? doc.get_selected_text (false) : ""; + return text.split ("\n", 2)[0]; } public bool has_successful_search () { @@ -1158,11 +1161,10 @@ namespace Scratch { if (show_find_action.enabled) { show_find_action.activate (new Variant ("b", true)); } - } else if (!search_bar.is_focused) { - var selected_text = get_selected_text (); - if (selected_text != "") { - search_bar.set_search_entry_text (selected_text); - } + } + + if (!search_bar.is_focused || search_bar.entry_text == "") { + search_bar.set_search_entry_text (get_selected_text_for_search ()); } search_bar.search (); @@ -1192,19 +1194,18 @@ namespace Scratch { } private void action_find_global (SimpleAction action, Variant? param) { - var current_doc = get_current_document (); - var selected_text = current_doc != null ? current_doc.get_selected_text (false) : ""; - selected_text = selected_text.split ("\n", 2)[0]; - var search_term = ""; - if (search_bar.is_focused || selected_text == "") { - search_term = search_bar.entry_text; + if (!search_bar.is_focused || search_bar.entry_text == "") { + search_term = get_selected_text_for_search (); } else { - search_term = selected_text; + search_term = search_bar.entry_text; } folder_manager_view.search_global (get_target_path_for_actions (param), search_term); search_bar.set_search_entry_text (search_term); + if (!search_bar.is_revealed) { + action_toggle_show_find (); + } } private void update_find_actions () { @@ -1230,6 +1231,9 @@ namespace Scratch { search_bar.reveal (to_show); if (to_show) { search_bar.focus_search_entry (); + if (search_bar.entry_text == "") { // Should always be true atm as entry cleared on hiding + search_bar.set_search_entry_text (get_selected_text_for_search ()); + } } } diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index a0d897bfe..8752a91b6 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -82,6 +82,12 @@ namespace Scratch.Widgets { } } + public uint transition_time_msec { + get { + return revealer.transition_duration + 10; + } + } + public SearchBar (MainWindow window) { Object (window: window); } @@ -489,10 +495,11 @@ namespace Scratch.Widgets { replace_entry.grab_focus (); } - public void reveal (bool visible) { - revealer.reveal_child = visible; - if (!visible) { - search_entry.text = ""; + public void reveal (bool to_reveal) { + revealer.reveal_child = to_reveal; + // Clear entry when searchbar is hidden + if (is_revealed && !to_reveal) { + set_search_entry_text (""); } } From 0661e5a140aa8898ae42cdd55a0bbfe5cdd986ff Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 4 Feb 2025 14:40:20 +0000 Subject: [PATCH 6/8] Focus search entry on search; Ensure non-null search term --- src/MainWindow.vala | 7 ++++--- src/Widgets/SearchBar.vala | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 5777bcf77..56b7c02be 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -731,8 +731,9 @@ namespace Scratch { // Returns "" if no selection public string get_selected_text_for_search () { var doc = get_current_document (); - var text = doc != null ? doc.get_selected_text (false) : ""; - return text.split ("\n", 2)[0]; + var selected_text = doc != null ? doc.get_selected_text (false) : ""; + var search_term = selected_text.split ("\n", 2)[0]; + return search_term ?? ""; } public bool has_successful_search () { @@ -1167,7 +1168,7 @@ namespace Scratch { } } - if (!search_bar.is_focused || search_bar.entry_text == "") { + if (search_bar.entry_text == "") { search_bar.set_search_entry_text (get_selected_text_for_search ()); } diff --git a/src/Widgets/SearchBar.vala b/src/Widgets/SearchBar.vala index 8752a91b6..56a718631 100644 --- a/src/Widgets/SearchBar.vala +++ b/src/Widgets/SearchBar.vala @@ -360,6 +360,7 @@ namespace Scratch.Widgets { } public bool search () { + search_entry.grab_focus (); if (search_context == null) { return false; } From 6071b7a95fe37d94a0a60db6875d105b262fcaa0 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 4 Feb 2025 15:17:47 +0000 Subject: [PATCH 7/8] Always search for any selected text after Control + F --- src/MainWindow.vala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 56b7c02be..37bf70593 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -1168,8 +1168,9 @@ namespace Scratch { } } - if (search_bar.entry_text == "") { - search_bar.set_search_entry_text (get_selected_text_for_search ()); + var selected_text_for_search = get_selected_text_for_search (); + if (selected_text_for_search != "") { + search_bar.set_search_entry_text (selected_text_for_search); } search_bar.search (); From 7a2c6dec96b563da5ab7522891d6cf3318580801 Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Tue, 11 Feb 2025 12:21:34 +0000 Subject: [PATCH 8/8] Set searchbar entry after global search --- src/MainWindow.vala | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/MainWindow.vala b/src/MainWindow.vala index ce03fa9e1..27bd608c4 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -126,7 +126,7 @@ namespace Scratch { private Services.GitManager git_manager; private const ActionEntry[] ACTION_ENTRIES = { - { ACTION_FIND, action_find}, + { ACTION_FIND, action_find, "s"}, { ACTION_FIND_NEXT, action_find_next }, { ACTION_FIND_PREVIOUS, action_find_previous }, { ACTION_FIND_GLOBAL, action_find_global, "s" }, @@ -193,7 +193,7 @@ namespace Scratch { } static construct { - action_accelerators.set (ACTION_FIND, "f"); + action_accelerators.set (ACTION_FIND + "::", "f"); action_accelerators.set (ACTION_FIND_NEXT, "g"); action_accelerators.set (ACTION_FIND_PREVIOUS, "g"); action_accelerators.set (ACTION_FIND_GLOBAL + "::", "f"); @@ -738,7 +738,6 @@ namespace Scratch { } // If selected text covers more than one line return just the first. - // Returns "" if no selection public void set_selected_text_for_search () { var doc = get_current_document (); var selected_text = doc != null ? doc.get_selected_text (false) : ""; @@ -1178,7 +1177,11 @@ namespace Scratch { } /** Not a toggle action - linked to keyboard short cut (Ctrl-f). **/ - private void action_find () { + private void action_find (SimpleAction action, Variant? param) { + find (param != null ? param.get_string () : ""); + } + + private void find (string search_term = "") { if (!search_bar.is_revealed) { var show_find_action = Utils.action_from_group (ACTION_TOGGLE_SHOW_FIND, actions); if (show_find_action.enabled) { @@ -1186,13 +1189,17 @@ namespace Scratch { } } - set_selected_text_for_search (); + if (search_term != "") { + search_bar.set_search_entry_text (search_term); + } else { + set_selected_text_for_search (); + } search_bar.search (); } private void action_show_replace (SimpleAction action) { - action_find (); + find (); // May have to wait for the search bar to be revealed before we can grab focus if (search_bar.is_revealed) { @@ -1231,12 +1238,10 @@ namespace Scratch { } else { // Fallback to standard search warning ("Unable to perform global search - search document instead"); - action_find (); + find (); } - if (!search_bar.is_revealed) { - action_toggle_show_find (); - } + // No need to reveal searchbar - handled by subsequent find action. } private void update_find_actions () { @@ -1262,7 +1267,7 @@ namespace Scratch { search_bar.reveal (to_show); if (to_show) { search_bar.focus_search_entry (); - if (search_bar.entry_text == "") { // Should always be true atm as entry cleared on hiding + if (search_bar.entry_text == "") { set_selected_text_for_search (); } }