private void AddBlock(SectionBlock.Data data) { var block = new SectionBlock(data); if (block.Type == BlockType.Main) { _mainBlock = block; } else if (block.Type == BlockType.Links) { _linksBlock = block; } else { _normalBlocks.Add(block); } _allBlocks.Add(block); block.LeftClick += BlockLeftClick; block.RightClick += BlockRightClick; }
public async Task Diagram(string word, int fileId, Action <IEnumerable <SectionBlock.Data> > handleBlocksAction) { if (string.IsNullOrWhiteSpace(word)) { return; } var analytics = await Model.Analyzed; if (!analytics.Files.TryGetValue(fileId, out AData.FileDef file)) { return; } if (!file.Sections.TryGetValue(word, out AData.SectionDef section)) { return; } IEnumerable <AData.Location> FindRefs(string name) { analytics.References.TryGetValue("s:" + name, out AData.Reference r); return((r?.Locations ?? Enumerable.Empty <AData.Location>()).Distinct(new AData.LocationComparer())); } var sectonGroups = Model.SectionGroups; var sectionProps = new List <object>(); var sectionLinks = new List <object>(); var sectionUsages = new List <object>(); var otherBlocks = new List <SectionBlock.Data>(); var namedBlocks = new Dictionary <string, SectionBlock.Data>(StringComparer.OrdinalIgnoreCase); var anotherRefs = FindRefs(word).Where(x => x.FileId != fileId); bool AddNamedBlock(string prop, params object[] data) { foreach (var sectonGroup in sectonGroups) { foreach (var pattern in sectonGroup.Value.Patterns) { if (pattern.IsMatch(prop)) { if (!namedBlocks.TryGetValue(sectonGroup.Key, out SectionBlock.Data d)) { namedBlocks[sectonGroup.Key] = d = new SectionBlock.Data { Text = sectonGroup.Key, Type = BlockType.Default }; otherBlocks.Add(d); } d.Properties = d.Properties.Concat(data).ToArray(); return(true); } } } return(false); } foreach (var location in anotherRefs) { sectionUsages.Add(new AData.LocationGroup($"{word.ToUpper()} ({Path.GetFileName(FilePath(location.FileId))})", word, new[] { location })); } // collection all props of select section foreach (var propertyDef in section.Properties) { var values = propertyDef.Value.Value.Split(','); if (values.Length == 1) { var refs = FindRefs(propertyDef.Value.Value); // dont include current section location if (propertyDef.Value.Value.IgnoreCaseEqual(word)) { refs = refs.Where(x => x.FileId != fileId); } var distinctRefs = new HashSet <AData.Location>(); foreach (var location in refs) { if (distinctRefs.Any(x => x.FileId == location.FileId && x.Position == location.Position)) { continue; } distinctRefs.Add(location); } var propText = $"{propertyDef.Key} = {propertyDef.Value.Value}"; var locationGroup = new AData.LocationGroup(propText, propertyDef.Value.Value, distinctRefs); if (locationGroup.Locations.Length > 0) { if (!AddNamedBlock(propertyDef.Key, locationGroup)) { sectionLinks.Add(locationGroup); } } else { if (!AddNamedBlock(propertyDef.Key, propText)) { sectionProps.Add(propText); } } } else { var links = new List <object>(); // multiple value foreach (var value in values) { if (float.TryParse(value, out _)) { links.Add(value); } else { // try to find out link var refs = FindRefs(value); var distinctRefs = new HashSet <AData.Location>(); foreach (var location in refs) { if (distinctRefs.Any(x => x.FileId == location.FileId && x.Position == location.Position)) { continue; } distinctRefs.Add(location); } var locationGroup = new AData.LocationGroup(value, value, distinctRefs); if (locationGroup.Locations.Length > 0) { links.Add(locationGroup); } else { links.Add(value); } } } if (links.OfType <AData.LocationGroup>().Any()) { if (!AddNamedBlock(propertyDef.Key, links.Select(l => { if (l is AData.LocationGroup lg) { return(new AData.LocationGroup($"{propertyDef.Key} = {lg.Text}", lg.Key, lg.Locations) as object); } return($"{propertyDef.Key} = {l}" as object); }).ToArray())) { otherBlocks.Add(new SectionBlock.Data { Text = propertyDef.Key, Type = BlockType.Default, Properties = links.ToArray() }); } } else { var propText = $"{propertyDef.Key} = {values.First()}"; if (!AddNamedBlock(propertyDef.Key, propText)) { // not contains any link => simple value sectionProps.Add(propText); } } } } foreach (var analyticsFile in analytics.Files) { foreach (var sectionDef in analyticsFile.Value.Sections) { if (fileId == analyticsFile.Key && sectionDef.Key.IgnoreCaseEqual(word)) { continue; } foreach (var propertyDef in sectionDef.Value.Properties) { if (float.TryParse(propertyDef.Value.Value, out float _)) { } else if (propertyDef.Value.Value.IgnoreCaseEqual(word) || propertyDef.Value.Value.StartsWith(word + ",", StringComparison.OrdinalIgnoreCase) || propertyDef.Value.Value.EndsWith("," + word, StringComparison.OrdinalIgnoreCase) || propertyDef.Value.Value.IndexOf("," + word + ",", StringComparison.OrdinalIgnoreCase) != -1) { // find location if (analytics.References.TryGetValue("s:" + sectionDef.Key, out AData.Reference refs)) { var location = refs.Locations.FirstOrDefault(x => x.FileId == analyticsFile.Key); if (location != null) { var text = $"{sectionDef.Key} » {propertyDef.Key} = {propertyDef.Value.Value}"; sectionUsages.Add(new AData.LocationGroup(text, sectionDef.Key, new[] { location })); } } } } } } var allBlocks = new List <SectionBlock.Data> { new SectionBlock.Data { Text = $"{word.ToUpper()} ({Path.GetFileName(file.FullPath)})", Type = BlockType.Main, Properties = sectionProps.ToArray() } }; if (sectionLinks.Count > 0) { allBlocks.Add(new SectionBlock.Data { Text = "Links", Type = BlockType.Links, Properties = sectionLinks.ToArray() }); } if (sectionUsages.Count > 0) { allBlocks.Add(new SectionBlock.Data { Text = "Usages", Type = BlockType.Usages, Properties = sectionUsages.ToArray() }); } allBlocks.AddRange(otherBlocks); // apply section styles foreach (var block in allBlocks) { if (Model.SectionDetails.TryGetValue(block.Type == BlockType.Main ? "Main" : block.Text, out SectionStyle s)) { block.Style = s; } } handleBlocksAction(allBlocks); }