// Very awkward procedure that accesses global state in the name of only doing one iteration internal static void AddTagsToFMAndGlobalList( string tagsToAdd, FMCategoriesCollection existingFMTags, bool addToGlobalList = true) { if (tagsToAdd.IsWhiteSpace()) { return; } string[] tagsArray = tagsToAdd.Split(CA_CommaSemicolon, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < tagsArray.Length; i++) { if (!TryGetCatAndTag(tagsArray[i], out string cat, out string tag) || cat.IsEmpty() || tag.IsEmpty()) { continue; } #region FM tags if (existingFMTags.TryGetValue(cat, out FMTagsCollection tagsList)) { tagsList.Add(tag); } else { existingFMTags.Add(cat, new FMTagsCollection { tag }); } #endregion if (!addToGlobalList) { continue; } #region Global tags if (GlobalTags.TryGetValue(cat, out FMTagsCollection globalTagsList)) { globalTagsList.Add(tag); } else { GlobalTags.Add(cat, new FMTagsCollection { tag }); } #endregion } }
private void RemoveAllButtons_Click(object sender, EventArgs e) { FMCategoriesCollection tags = sender == RemoveAllAndButton ? TagsFilter.AndTags : sender == RemoveAllOrButton ? TagsFilter.OrTags : TagsFilter.NotTags; tags.Clear(); FillTreeView(tags); }
private void FillTreeView(FMCategoriesCollection tags) { var tv = tags == TagsFilter.AndTags ? AndTreeView : tags == TagsFilter.OrTags ? OrTreeView : NotTreeView; tv.SuspendDrawing(); tv.Nodes.Clear(); ControlUtils.FillTreeViewFromTags_Sorted(tv, tags); tv.ExpandAll(); tv.ResumeDrawing(); CheckTagInAny(); }
internal FilterTagsForm(FMCategoriesCollection sourceTags, TagsFilter tagsFilter) { #if DEBUG InitializeComponent(); #else InitializeComponentSlim(); #endif tagsFilter.DeepCopyTo(TagsFilter); if (Config.DarkMode) { SetThemeBase(Config.VisualTheme); } Localize(); var tv = OriginTreeView; try { tv.BeginUpdate(); ControlUtils.FillTreeViewFromTags_Sorted(tv, sourceTags); tv.ExpandAll(); tv.SelectedNode = tv.Nodes[0]; } finally { tv.EndUpdate(); } if (TagsFilter.AndTags.Count > 0) { FillTreeView(TagsFilter.AndTags); } if (TagsFilter.OrTags.Count > 0) { FillTreeView(TagsFilter.OrTags); } if (TagsFilter.NotTags.Count > 0) { FillTreeView(TagsFilter.NotTags); } }
private void AddTagsButtons_Click(object sender, EventArgs e) { var o = OriginTreeView; if (o.SelectedNode == null) { return; } FMCategoriesCollection 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; if (filteredTags.TryGetValue(cat, out FMTagsCollection tags)) { if (isCategory) { tags.Clear(); } else { tags.Add(o.SelectedNode.Text); } } else { var item = new FMTagsCollection(); filteredTags.Add(cat, item); if (!isCategory) { item.Add(o.SelectedNode.Text); } } FillTreeView(filteredTags); }
internal static string TagsToString(FMCategoriesCollection tagsList, bool writeEmptyCategories) { var intermediateTagsList = new List <string>(); foreach (CatAndTagsList item in tagsList) { if (item.Tags.Count == 0 && writeEmptyCategories) { intermediateTagsList.Add(item.Category + ":"); } else { foreach (string tag in item.Tags) { intermediateTagsList.Add(item.Category + ":" + tag); } } } return(string.Join(",", intermediateTagsList)); }
private void RemoveSelectedButtons_Click(object sender, EventArgs e) { FMCategoriesCollection tags = sender == RemoveSelectedAndButton ? TagsFilter.AndTags : sender == RemoveSelectedOrButton ? TagsFilter.OrTags : TagsFilter.NotTags; var tv = sender == RemoveSelectedAndButton ? AndTreeView : sender == RemoveSelectedOrButton ? OrTreeView : NotTreeView; if (tv.SelectedNode == null) { return; } // Parent node (category) if (tv.SelectedNode.Parent == null) { tags.Remove(tv.SelectedNode.Text); } // Child node (tag) else { string cat = tv.SelectedNode.Parent.Text; if (tags.TryGetValue(cat, out FMTagsCollection tagsList)) { tagsList.Remove(tv.SelectedNode.Text); if (tagsList.Count == 0) { tags.Remove(cat); } } } FillTreeView(tags); }
private static void ReadFilterTags(string tagsToAdd, FMCategoriesCollection existingTags) { if (tagsToAdd.IsWhiteSpace()) { return; } // We need slightly different logic for this vs. the FM tag adder, to wit, we support tags of the // form "category:" (with no tags list). This is because we allow filtering by entire category, // whereas we don't allow FMs to have categories with no tags in them. string[] tagsArray = tagsToAdd.Split(CA_CommaSemicolon, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < tagsArray.Length; i++) { if (!FMTags.TryGetCatAndTag(tagsArray[i], out string cat, out string tag) || cat.IsEmpty()) { continue; } if (existingTags.TryGetValue(cat, out FMTagsCollection tagsList)) { if (!tag.IsEmpty()) { tagsList.Add(tag); } } else { var newTagsList = new FMTagsCollection(); if (!tag.IsEmpty()) { newTagsList.Add(tag); } existingTags.Add(cat, newTagsList); } } }
private void CheckTagInAny() { var o = OriginTreeView; if (o.SelectedNode == null) { return; } // Parent node = category, child node = tag bool isCategory = o.SelectedNode.Parent == null; string cat = isCategory ? o.SelectedNode.Text : o.SelectedNode.Parent !.Text; bool tagInAny = false; for (int t = 0; t < 3; t++) { FMCategoriesCollection filteredTags = t switch { 0 => TagsFilter.AndTags, 1 => TagsFilter.OrTags, _ => TagsFilter.NotTags }; if (filteredTags.TryGetValue(cat, out FMTagsCollection tagsList) && (isCategory || tagsList.Contains(o.SelectedNode.Text) || (cat == o.SelectedNode.Parent !.Text && tagsList.Count == 0))) { tagInAny = true; } } AndButton.Enabled = !tagInAny; OrButton.Enabled = !tagInAny; NotButton.Enabled = !tagInAny; }
private static string TagsToString(FMCategoriesCollection tagsList) { return(FMTags.TagsToString(tagsList, writeEmptyCategories: true)); }