/// <summary> /// Add the specified layer fragment to this part. Any other existing /// fragment eventually overlapping the new one will be removed. /// </summary> /// <param name="fragment">The new fragment.</param> /// <exception cref="ArgumentNullException">null item</exception> public void AddFragment(TFragment fragment) { if (fragment == null) { throw new ArgumentNullException(nameof(fragment)); } if (Fragments == null) { Fragments = new List <TFragment>(); } // remove all the existing overlapping fragments TokenTextLocation newLoc = TokenTextLocation.Parse(fragment.Location); for (int i = Fragments.Count - 1; i > -1; i--) { TokenTextLocation loc = TokenTextLocation.Parse(Fragments[i].Location); if (newLoc.Overlaps(loc)) { Fragments.RemoveAt(i); } } Fragments.Add(fragment); }
/// <summary> /// Gets the fragments hints for the specified list of editing /// operations on the base text. /// </summary> /// <param name="operations">The operations.</param> /// <returns>The hints list, one hint per fragment.</returns> /// <exception cref="ArgumentNullException">operations</exception> public IList <LayerHint> GetFragmentHints( IList <YXEditOperation> operations) { if (operations == null) { throw new ArgumentNullException(nameof(operations)); } List <LayerHint> hints = new List <LayerHint>(); foreach (AnonFragment fr in Fragments) { TokenTextLocation frLoc = TokenTextLocation.Parse(fr.Location); LayerHint hint = new LayerHint { Location = fr.Location }; hints.Add(hint); foreach (YXEditOperation operation in operations) { TokenTextLocation opLoc = TokenTextLocation.Parse( operation.OldLocation); bool isOverlap = frLoc.Overlaps(opLoc); bool isCoincident = !frLoc.IsRange && frLoc.A.Y == opLoc.A.Y && frLoc.A.X == opLoc.A.X; switch (operation.Operator) { case YXEditOperation.EQU: if (isOverlap && operation.OldLocation != operation.Location) { hint.EditOperation = operation.ToString(); hint.Description = $"text \"{operation.Value}\" moved"; if (isCoincident) { hint.ImpactLevel = 2; hint.PatchOperation = $"mov {operation.OldLocation} {operation.Location}"; } else { hint.ImpactLevel = 1; } } break; case YXEditOperation.DEL: if (isOverlap) { hint.EditOperation = operation.ToString(); hint.Description = $"text \"{operation.Value}\" deleted"; if (isCoincident) { hint.ImpactLevel = 2; hint.PatchOperation = $"del {operation.OldLocation}"; } else { hint.ImpactLevel = 1; } } break; case YXEditOperation.MVD: if (isCoincident) { hint.EditOperation = operation.ToString(); hint.Description = $"text \"{operation.Value}\" moved"; hint.ImpactLevel = 2; string newLoc = operations.First(o => o.GroupId == operation.GroupId && o != operation).OldLocation; hint.PatchOperation = $"mov {operation.Location} {newLoc}"; break; } if (isOverlap) { hint.EditOperation = operation.ToString(); hint.Description = $"text \"{operation.Value}\" moved"; hint.ImpactLevel = 1; } break; case YXEditOperation.REP: if (isOverlap) { hint.EditOperation = operation.ToString(); hint.Description = $"text \"{operation.OldValue}\" " + $"replaced with \"{operation.Value}\""; hint.ImpactLevel = 1; } break; // no hint for ins/mvi as relocations are already // processed for equ } } } return(hints); }