public bool Remove(IEnumerable <ConversationNode> nodes, IEnumerable <NodeGroup> groups, ILocalizationEngine localization) { nodes = nodes.ToList(); groups = groups.ToList(); bool removeNodes = nodes.Any(); bool removeGroups = groups.Any(); List <Action> undoActions = new List <Action>(); List <Action> redoActions = new List <Action>(); if (nodes.Any(n => !CanRemoveFromData(n, () => false))) { if (!PromptNodeDeletion()) { return(false); } } if (removeNodes) { //Make sure all the nodes are added before trying to link them foreach (var node in nodes) { var n = node; undoActions.Add(() => { m_nodes.Add(n); }); } foreach (var node in nodes) { var n = node; var actions = n.GetNodeRemoveActions(); //Ensure that the localization engine is up to date in terms of usage of localized data foreach (var parameter in n.Data.Parameters.OfType <ILocalizedStringParameter>()) { SimpleUndoPair clearLocalization = localization.ClearLocalizationAction(Id <LocalizedStringType> .ConvertFrom(parameter.TypeId), parameter.Value); undoActions.Add(clearLocalization.Undo); redoActions.Add(clearLocalization.Redo); } var containingGroups = m_groups.Where(g => g.Contents.Contains(n.Data.NodeId)).Evaluate(); undoActions.Add(() => { actions.Undo(); //Connect after adding the node foreach (var group in containingGroups) { group.Contents.Add(n.Data.NodeId); } m_audioProvider.UpdateUsage(n); }); redoActions.Add(() => { actions.Redo(); //Disconnect before removing the node m_nodes.Remove(n); foreach (var group in containingGroups) { group.Contents.Remove(n.Data.NodeId); } NodesDeleted.Execute(); }); } } if (removeGroups) { List <NodeGroup> toAdd = new List <NodeGroup>(groups); undoActions.Add(() => { m_groups.AddRange(toAdd); }); redoActions.Add(() => { m_groups.RemoveRange(toAdd); }); } Action undo = () => { using (m_audioProvider.SuppressUpdates()) foreach (Action action in undoActions) { action(); } }; Action redo = () => { using (m_audioProvider.SuppressUpdates()) foreach (Action action in redoActions) { action(); } }; string message; if (removeNodes && removeGroups) { message = "Deleted elements"; } else if (removeNodes) { message = "Deleted nodes"; } else if (removeGroups) { message = "Removed groupings"; } else { throw new InternalLogicException("Something went wrong :("); } UndoableFile.Change(new GenericUndoAction(undo, redo, message)); return(true); }
private SimpleUndoPair InnerAddNodes(IEnumerable <ConversationNode> nodes, IEnumerable <NodeGroup> groups, ILocalizationEngine localization) { List <Action> undoActions = new List <Action>(); List <Action> redoActions = new List <Action>(); //Set up actions for adding/removing the nodes foreach (var node in nodes) { var n = node; SimpleUndoPair actions = n.GetNodeRemoveActions(); //Ensure that the localization engine is up to date in terms of usage of localized data foreach (var parameter in n.Data.Parameters.OfType <ILocalizedStringParameter>()) { if (parameter.Value != null) { SimpleUndoPair clearLocalization = localization.ClearLocalizationAction(Id <LocalizedStringType> .ConvertFrom(parameter.TypeId), parameter.Value); undoActions.Add(clearLocalization.Redo); redoActions.Add(clearLocalization.Undo); } } var containingGroups = m_groups.Where(g => g.Contents.Contains(n.Data.NodeId)).Evaluate(); redoActions.Add(() => { m_nodes.Add(n); m_audioProvider.UpdateUsage(n); foreach (var group in containingGroups) { group.Contents.Add(n.Data.NodeId); } actions.Undo(); //Undo the node removal }); undoActions.Add(() => { if (CanRemoveFromData(n, PromptNodeDeletion)) { m_nodes.Remove(n); } foreach (var group in containingGroups) { group.Contents.Remove(n.Data.NodeId); } actions.Redo(); //Redo the node removal NodesDeleted.Execute(); }); } //Set up actions for adding/removing nodes from other groups that are gaining/losing their grouping due to removing/adding new groups foreach (var group in groups) { foreach (var node in group.Contents) { var n = node; var old = m_groups.SingleOrDefault(g => g.Contents.Contains(n)); if (old != null) { undoActions.Add(() => old.Contents.Add(n)); redoActions.Add(() => old.Contents.Remove(n)); } } } //Set up actions for adding/removing the groups undoActions.Add(() => { foreach (var group in groups.Reverse()) { m_groups.Remove(group); } }); redoActions.Add(() => { m_groups.AddRange(groups); }); return(new SimpleUndoPair { Undo = () => { using (m_audioProvider.SuppressUpdates()) foreach (Action action in undoActions) { action(); } }, Redo = () => { using (m_audioProvider.SuppressUpdates()) foreach (Action action in redoActions) { action(); } }, }); }