private Node CreateNode([NotNull] string key) { var content = new XElement(_valueNodeName); content.Add(new XText(string.Empty)); var entry = new XElement(_dataNodeName, new XAttribute(_nameAttributeName, key), new XAttribute(_spaceAttributeName, @"preserve")); entry.Add(content, new XText("\n ")); var fileContentSorting = _configuration.EffectiveResXSortingComparison; if (fileContentSorting.HasValue) { SortAndAdd(fileContentSorting.Value, entry); } else { DocumentRoot.Add(entry); } UpdateNodes(); try { new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext()).StartNew(() => Container.OnItemOrderChanged(this)); } catch (InvalidOperationException) { // for scripting deferred notifications are not needed, so if the current thread does not support a synchronization context, just go without. } return(_nodes[key]); }
private Node CreateNode([NotNull] string key) { var content = new XElement(_valueNodeName); content.Add(new XText(string.Empty)); var entry = new XElement(_dataNodeName, new XAttribute(_nameAttributeName, key), new XAttribute(_spaceAttributeName, @"preserve")); entry.Add(content, new XText("\n ")); var fileContentSorting = _configuration.EffectiveResXSortingComparison; if (fileContentSorting.HasValue) { SortAndAdd(fileContentSorting.Value, entry); } else { DocumentRoot.Add(entry); } UpdateNodes(); Dispatcher.CurrentDispatcher.BeginInvoke(() => Container.OnItemOrderChanged(this)); return(_nodes[key]); }
private bool SortAndAdd(StringComparison stringComparison, XElement?newNode) { var comparer = new DelegateComparer <string>((left, right) => string.Compare(left, right, stringComparison)); string GetName(XElement node) => node.Attribute(_nameAttributeName)?.Value.TrimStart('>') ?? string.Empty; var nodes = DocumentRoot .Elements(_dataNodeName) .ToArray(); var sortedNodes = nodes .OrderBy(GetName, comparer) .ToArray(); var hasContentChanged = SortNodes(nodes, sortedNodes); if (newNode == null) { return(hasContentChanged); } var newNodeName = GetName(newNode); var nextNode = sortedNodes.FirstOrDefault(node => comparer.Compare(GetName(node), newNodeName) > 0); if (nextNode != null) { nextNode.AddBeforeSelf(newNode); } else { DocumentRoot.Add(newNode); } return(true); }
/// <summary> /// An undocumented "feature" of XElement.Add is that it *SOMETIMES* (and only sometimes) adds a copy of the passed XElement, not the element itself. /// Nothing we can do about that. However, this method returns the created copy for further reference. /// Also assigns a unique ID to the shape, if the existing ID is taken. /// </summary> public XElement AddShape(XElement shape) { VerifyState(ModelState.Ready, ModelState.Busy); String idString = shape.GetStringAttribute("Id"); if (idString != "" && GetShapeById(idString) != null) { shape.SetAttributeValue("Id", GetUniqueId()); } DocumentRoot.Add(shape); XElement copy = (XElement)DocumentRoot.LastNode; return(copy); }
private bool SortNodes([NotNull, ItemNotNull] XElement[] nodes, [NotNull, ItemNotNull] XElement[] sortedNodes) { if (nodes.SequenceEqual(sortedNodes)) { return(false); } foreach (var item in nodes) { item.Remove(); } foreach (var item in sortedNodes) { DocumentRoot.Add(item); } return(true); }