diff --git a/src/docs/history.txt b/src/docs/history.txt index 212e861..db6a345 100644 --- a/src/docs/history.txt +++ b/src/docs/history.txt @@ -5,6 +5,11 @@ https://news.ycombinator.com/news (9 jan 2016) quora +1.6.31b +- solved #47 filtering / finding (next prev) - show progress + - busy cursor when this happens + - show progress in status bar + 1.6.31a - find first/next/prev happen on a different thread diff --git a/src/lw_common/ui/log_view/log_view.Designer.cs b/src/lw_common/ui/log_view/log_view.Designer.cs index cdf6da7..1d6bccc 100644 --- a/src/lw_common/ui/log_view/log_view.Designer.cs +++ b/src/lw_common/ui/log_view/log_view.Designer.cs @@ -61,6 +61,7 @@ private void InitializeComponent() this.panel1 = new System.Windows.Forms.Panel(); this.label1 = new System.Windows.Forms.Label(); this.edit = new lw_common.ui.smart_readonly_textbox(); + this.updateCursor = new System.Windows.Forms.Timer(this.components); ((System.ComponentModel.ISupportInitialize)(this.list)).BeginInit(); this.panel1.SuspendLayout(); this.SuspendLayout(); @@ -375,6 +376,7 @@ private void InitializeComponent() // edit // this.edit.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.edit.force_hide = false; this.edit.Location = new System.Drawing.Point(-200, 29); this.edit.Multiline = false; this.edit.Name = "edit"; @@ -384,6 +386,12 @@ private void InitializeComponent() this.edit.TabIndex = 5; this.edit.Text = ""; // + // updateCursor + // + this.updateCursor.Enabled = true; + this.updateCursor.Interval = 200; + this.updateCursor.Tick += new System.EventHandler(this.updateCursor_Tick); + // // log_view // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -441,5 +449,6 @@ private void InitializeComponent() internal BrightIdeasSoftware.OLVColumn ctx13Col; internal BrightIdeasSoftware.OLVColumn ctx14Col; internal BrightIdeasSoftware.OLVColumn ctx15Col; + private System.Windows.Forms.Timer updateCursor; } } diff --git a/src/lw_common/ui/log_view/log_view.cs b/src/lw_common/ui/log_view/log_view.cs index edfef95..59beec5 100644 --- a/src/lw_common/ui/log_view/log_view.cs +++ b/src/lw_common/ui/log_view/log_view.cs @@ -119,6 +119,8 @@ public partial class log_view : UserControl, IDisposable // last time we received the last scroll event private DateTime scrolling_time_ = DateTime.MinValue; + private int is_searching_ = 0; + public log_view(Form parent, string name) { Debug.Assert(parent is log_view_parent); @@ -363,6 +365,25 @@ internal filter filter { get { return filter_; } } + private string last_search_status_ = ""; + public string search_status { + get { + string status = ""; + if (is_searching_ > 0) + status = "Seaching " + cur_search.friendly_name; + else if (model_.is_running_filter) + status = "Running Filter"; + + if (status != "") { + string suffix = new string('.', DateTime.Now.Second % 5); + status += " " + suffix; + } + bool was_seaching = last_search_status_ != ""; + last_search_status_ = status; + // after search complete, return ' ', so that we clear the search status visually + return was_seaching && status == "" ? " " : status; + } + } private filter.match create_match_object(BitArray matches, font_info font, line line, int line_idx) { return is_full_log ? new full_log_match_item(matches, font, line, line_idx, this) : new match_item(matches, font, line, line_idx, this); } @@ -1590,6 +1611,11 @@ public void escape() { public async void search_next() { + if (is_searching_ > 0) { + // we're already searching (asynchronously) + util.beep(util.beep_type.err); + return; + } /* 1.2.7+ implemented f3/shift-f3 on smart-edit first note: this will never replace search form -> since there you can have extra settings: regexes, case-sensitivity ,full word */ @@ -1600,15 +1626,22 @@ public async void search_next() { string sel_text = edit.sel_text.ToLower(); await Task.Run((() => { + ++is_searching_ ; if (cur_search_ != null || sel_text != "") search_for_text_next(); else if (cur_filter_row_idx_ >= 0) search_for_next_match(cur_filter_row_idx_); + --is_searching_ ; })); lv_parent.sel_changed(log_view_sel_change_type.search); } public async void search_prev() { + if (is_searching_ > 0) { + // we're already searching (asynchronously) + util.beep(util.beep_type.err); + return; + } /* 1.2.7+ implemented f3/shift-f3 on smart-edit first note: this will never replace search form -> since there you can have extra settings: regexes, case-sensitivity ,full word */ @@ -1619,16 +1652,24 @@ public async void search_prev() { string sel_text = edit.sel_text.ToLower(); await Task.Run((() => { + ++is_searching_; if (cur_search_ != null || sel_text != "") search_for_text_prev(); else if (cur_filter_row_idx_ >= 0) search_for_prev_match(cur_filter_row_idx_); + --is_searching_; })); lv_parent.sel_changed(log_view_sel_change_type.search); } // note: starts from the next row, or, if on row zero -> starts from row zero public async void search_for_text_first() { + if (is_searching_ > 0) { + // we're already searching (asynchronously) + util.beep(util.beep_type.err); + return; + } + if (item_count < 1) return; Debug.Assert(cur_search_ != null); @@ -1646,7 +1687,11 @@ public async void search_for_text_first() { ensure_row_visible(0); lv_parent.sel_changed(log_view_sel_change_type.search); } else - await Task.Run(() => search_for_text_next()); + await Task.Run(() => { + ++is_searching_; + search_for_text_next(); + --is_searching_; + }); } private bool row_contains_search_text(int row_idx, List visible_indexes) { @@ -2451,5 +2496,10 @@ private void log_view_SizeChanged(object sender, EventArgs e) { private void log_view_LocationChanged(object sender, EventArgs e) { edit.update_ui(); } + + private void updateCursor_Tick(object sender, EventArgs e) { + bool busy = is_searching_ > 0 || model_.is_running_filter; + list.Cursor = busy ? Cursors.WaitCursor : Cursors.IBeam; + } } } diff --git a/src/lw_common/ui/log_view/log_view.resx b/src/lw_common/ui/log_view/log_view.resx index c818963..1d44960 100644 --- a/src/lw_common/ui/log_view/log_view.resx +++ b/src/lw_common/ui/log_view/log_view.resx @@ -120,4 +120,7 @@ 17, 17 + + 83, 17 + \ No newline at end of file diff --git a/src/lw_common/ui/log_view/match/log_view_data_source.cs b/src/lw_common/ui/log_view/match/log_view_data_source.cs index 778964e..42f33d2 100644 --- a/src/lw_common/ui/log_view/match/log_view_data_source.cs +++ b/src/lw_common/ui/log_view/match/log_view_data_source.cs @@ -73,6 +73,8 @@ internal class log_view_data_source : AbstractVirtualListDataSource, IDisposable private int item_count_ = 0; + private bool is_running_filter_ = false; + public log_view_data_source(VirtualObjectListView lv, log_view parent ) : base(lv) { lv_ = lv; parent_ = parent; @@ -244,6 +246,10 @@ private int item_count_at_this_time { } } + public bool is_running_filter { + get { return is_running_filter_; } + } + public void refresh() { if ( items_.count == 0) @@ -269,10 +275,13 @@ private void update_filter_thread() { } // see what changed - if (filter_view) + if (filter_view) { // the user toggled on filtering + is_running_filter_ = true; run_filter(show_full_log); - + is_running_filter_ = false; + } + lock (this) { filter_view_ = filter_view_now_; show_full_log_ = show_full_log_now_; diff --git a/src/ui/log_wizard.cs b/src/ui/log_wizard.cs index bb5e34e..123612b 100644 --- a/src/ui/log_wizard.cs +++ b/src/ui/log_wizard.cs @@ -1349,7 +1349,12 @@ private void refresh_Tick(object sender, EventArgs ea) { try { refresh_cur_log_view(); - show_tips_.handle_tips(); + var sel = selected_view(); + string search_status = sel != null ? sel.search_status : ""; + if ( search_status != "") + status.set_status(search_status); + else + show_tips_.handle_tips(); } catch (Exception e) { logger.Error("Refresh error" + e.Message); }