private void AddTagsButtons_Click(object sender, EventArgs e) { var o = OriginTreeView; if (o.SelectedNode == null) { return; } CatAndTagsList filteredTags = sender == AndButton ? TagsFilter.AndTags : sender == OrButton ? TagsFilter.OrTags : TagsFilter.NotTags; // Parent node = category, child node = tag bool isCategory = o.SelectedNode.Parent == null; string cat = isCategory ? o.SelectedNode.Text : o.SelectedNode.Parent !.Text; CatAndTags?match = null; for (int i = 0; i < filteredTags.Count; i++) { if (filteredTags[i].Category == cat) { match = filteredTags[i]; } } if (match == null) { filteredTags.Add(new CatAndTags { Category = cat }); if (!isCategory) { CatAndTags last = filteredTags[filteredTags.Count - 1]; last.Tags.Add(o.SelectedNode.Text); } } else { if (isCategory) { match.Tags.Clear(); } else { string tag = o.SelectedNode.Text; if (!match.Tags.ContainsI(tag)) { match.Tags.Add(tag); } } } FillTreeView(filteredTags); }
// Very awkward procedure that accesses global state in the name of only doing one iteration // TODO: Test perf when 1000+ FMs each have a bunch of tags internal static void AddTagsToFMAndGlobalList(string tagsToAdd, CatAndTagsList existingFMTags) { if (tagsToAdd.IsEmpty()) { return; } string[] tagsArray = tagsToAdd.Split(CA_CommaSemicolon, StringSplitOptions.RemoveEmptyEntries); foreach (string item in tagsArray) { string cat, tag; int colonCount = item.CountCharsUpToAmount(':', 2); // No way josé if (colonCount > 1) { continue; } if (colonCount == 1) { int index = item.IndexOf(':'); cat = item.Substring(0, index).Trim().ToLowerInvariant(); tag = item.Substring(index + 1).Trim(); if (cat.IsEmpty() || tag.IsEmpty()) { continue; } } else { cat = "misc"; tag = item.Trim(); } // Note: We've already converted cat to lowercase, so we just do straight == to shave time off #region FM tags CatAndTags?match = null; for (int i = 0; i < existingFMTags.Count; i++) { if (existingFMTags[i].Category == cat) { match = existingFMTags[i]; break; } } if (match == null) { existingFMTags.Add(new CatAndTags { Category = cat }); existingFMTags[existingFMTags.Count - 1].Tags.Add(tag); } else { if (!match.Tags.ContainsI(tag)) { match.Tags.Add(tag); } } #endregion #region Global tags GlobalCatAndTags?globalMatch = null; for (int i = 0; i < GlobalTags.Count; i++) { if (GlobalTags[i].Category.Name == cat) { globalMatch = GlobalTags[i]; break; } } if (globalMatch == null) { GlobalTags.Add(new GlobalCatAndTags { Category = new GlobalCatOrTag { Name = cat, UsedCount = 1 } }); GlobalTags[GlobalTags.Count - 1].Tags.Add(new GlobalCatOrTag { Name = tag, UsedCount = 1 }); } else { globalMatch.Category.UsedCount++; GlobalCatOrTag?ft = null; for (int i = 0; i < globalMatch.Tags.Count; i++) { if (globalMatch.Tags[i].Name.EqualsI(tag)) { ft = globalMatch.Tags[i]; break; } } if (ft == null) { globalMatch.Tags.Add(new GlobalCatOrTag { Name = tag, UsedCount = 1 }); } else { ft.UsedCount++; } } #endregion } }