static IEnumerable<LogEntry> FilterResults(IEnumerable<LogEntry> result, LogSearchParameters searchParams) { if (searchParams.LogType == LogType.Pm) { if (searchParams.PmCharacterName != null && !searchParams.PmCharacterName.IsEmpty) { result = result.Where( s => s.PmConversationRecipient.Equals(searchParams.PmCharacterName)).ToArray(); } } return result; }
async void PerformSearch() { try { if (searching) throw new InvalidOperationException("Search already running"); searching = true; cancellationTokenSource = new CancellationTokenSource(); buttonCancelSearch.Visible = true; richTextBoxAllLines.Clear(); listBoxAllResults.Items.Clear(); dateTimePickerTimeFrom.Value = new DateTime( dateTimePickerTimeFrom.Value.Year, dateTimePickerTimeFrom.Value.Month, dateTimePickerTimeFrom.Value.Day, 0, 0, 0); dateTimePickerTimeTo.Value = new DateTime( dateTimePickerTimeTo.Value.Year, dateTimePickerTimeTo.Value.Month, dateTimePickerTimeTo.Value.Day, 23, 59, 59); var pmCharacter = GetPmCharacter(); var searchParams = new LogSearchParameters() { LogType = GetLogType(), CharacterName = new CharacterName(GetCharacter()), DateFrom = dateTimePickerTimeFrom.Value, DateTo = dateTimePickerTimeTo.Value, PmCharacterName = pmCharacter != null ? new CharacterName(pmCharacter) : null }; var searchType = GetSearchType(); var searchPhrase = GetPhrase(); var result = await logSearcherViewModel.Search(searchParams, cancellationTokenSource.Token); ParseAndDisplay(result, searchType, searchPhrase, searchParams); } catch (OperationCanceledException) { // cancelled //todo log } catch (Exception exception) { //todo logging, error display MessageBox.Show(exception.ToString()); } finally { searching = false; labelWorking.Hide(); buttonCancelSearch.Visible = false; listBoxAllResults.Visible = true; richTextBoxAllLines.Visible = true; buttonCommitSearch.Text = "Search"; richTextBoxAllLines.Select(0, 0); richTextBoxAllLines.ScrollToCaret(); } }
void ParseAndDisplay(IEnumerable<LogEntry> result, SearchTypeId searchTypeId, string searchPhrase, LogSearchParameters searchParams) { List<SingleSearchMatch> matches = new List<SingleSearchMatch>(); result = FilterResults(result, searchParams); List<string> results = new List<string>(); int currentLineBeginIndex = 0; var pattern = searchTypeId == SearchTypeId.RegexEscapedCaseIns ? ("(?i)" + Regex.Escape(searchPhrase)) : searchPhrase; foreach (var logEntry in result) { // restoring entry as string, so legacy code can be used without major rewrite var line = RestoreLogEntry(logEntry); results.Add(line); if (!string.IsNullOrWhiteSpace(searchPhrase)) { MatchCollection matchcollection = Regex.Matches(line, pattern); foreach (Match match in matchcollection) { long matchStart = currentLineBeginIndex + match.Index; long matchLength = match.Length; matches.Add(new SingleSearchMatch(matchStart, matchLength, BuildDateForMatch(line))); } } currentLineBeginIndex += line.Length + 1; // richtextbox seems to always add 1-length eol ?? } lastMatches = matches; buttonCommitSearch.Text = "Loading results..."; labelAllResults.Text = "All results: " + results.Count; richTextBoxAllLines.Visible = false; listBoxAllResults.Visible = false; labelWorking.Show(); this.Refresh(); richTextBoxAllLines.Clear(); listBoxAllResults.Items.Clear(); richTextBoxAllLines.Lines = results.ToArray(); if (matches.Any()) { bool tooManyToProcess = false; bool tooManyToHighlight = false; if (results.Count > 20000) tooManyToProcess = true; if (results.Count > 5000) tooManyToHighlight = true; if (!tooManyToProcess) { foreach (var searchmatch in matches) { string matchDesc = ""; matchDesc += searchmatch.MatchDate; if (!tooManyToHighlight) { richTextBoxAllLines.Select((int)searchmatch.BeginCharPos, (int)searchmatch.LenghtChars); richTextBoxAllLines.SelectionBackColor = Color.LightBlue; } listBoxAllResults.Items.Add(matchDesc); Application.DoEvents(); } } else { listBoxAllResults.Items.Add("too many matches"); listBoxAllResults.Items.Add("narrow the search"); } } }