private void PastedCopiedInstance(InstanceSave sourceInstance, ElementSave sourceElement, ElementSave targetElement, InstanceSave targetInstance, StateSave copiedState) { targetInstance.Name = StringFunctions.MakeStringUnique(targetInstance.Name, targetElement.Instances.Select(item => item.Name)); targetElement.Instances.Add(targetInstance); StateSave stateSave = copiedState; StateSave targetState; // We now have to copy over the states if (targetElement != sourceElement) { if (sourceElement.States.Count != 1) { MessageBox.Show("Only the default state variables will be copied since the source and target elements differ."); } targetState = targetElement.DefaultState; } else { targetState = SelectedState.Self.SelectedStateSave; } // why reverse loop? for (int i = stateSave.Variables.Count - 1; i > -1; i--) { // We may have copied over a group of instances. If so // the copied state may have variables for multiple instances. // We only want to apply the variables that work for the selected // object. VariableSave sourceVariable = stateSave.Variables[i]; if (sourceVariable.SourceObject == sourceInstance.Name) { VariableSave copiedVariable = sourceVariable.Clone(); copiedVariable.Name = targetInstance.Name + "." + copiedVariable.GetRootName(); // We don't want to copy exposed variables. // If we did, the user would have 2 variables exposed with the same. copiedVariable.ExposedAsName = null; targetState.Variables.Add(copiedVariable); } } // Copy over the VariableLists too for (int i = stateSave.VariableLists.Count - 1; i > -1; i--) { VariableListSave sourceVariableList = stateSave.VariableLists[i]; if (sourceVariableList.SourceObject == sourceInstance.Name) { VariableListSave copiedList = sourceVariableList.Clone(); copiedList.Name = targetInstance.Name + "." + copiedList.GetRootName(); targetState.VariableLists.Add(copiedList); } } // This used to be done here when we paste, but now we're // going to remove it when the cut happens - just like text // editors. Undo will handle this if we mess up. // bool shouldSaveSource = false; //if (mIsCtrlXCut) //{ // if (sourceElement.Instances.Contains(sourceInstance)) // { // // Not sure why we weren't just using // // ElementCommands here - maybe an oversight? // // This should improve things like // //sourceElement.Instances.Remove(sourceInstance); // ElementCommands.Self.RemoveInstance(sourceInstance, sourceElement); // shouldSaveSource = true; // } //} targetInstance.ParentContainer = targetElement; // We need to call InstanceAdd before we select the new object - the Undo manager expects it // This includes before other managers refresh PluginManager.Self.InstanceAdd(targetElement, targetInstance); WireframeObjectManager.Self.RefreshAll(true); GumCommands.Self.GuiCommands.RefreshElementTreeView(targetElement); SelectedState.Self.SelectedInstance = targetInstance; GumCommands.Self.FileCommands.TryAutoSaveElement(targetElement); }
public static void PasteInstanceSaves(List <InstanceSave> instancesToCopy, StateSave copiedState, ElementSave targetElement) { Dictionary <string, string> oldNewNameDictionary = new Dictionary <string, string>(); List <InstanceSave> newInstances = new List <InstanceSave>(); foreach (var sourceInstance in instancesToCopy) { ElementSave sourceElement = sourceInstance.ParentContainer; InstanceSave newInstance = sourceInstance.Clone(); // the original may have been defined in a base component. The new instance will not be // derived in the base, so let's get rid of that: newInstance.DefinedByBase = false; newInstances.Add(newInstance); if (targetElement != null) { var oldName = newInstance.Name; newInstance.Name = StringFunctions.MakeStringUnique(newInstance.Name, targetElement.Instances.Select(item => item.Name)); var newName = newInstance.Name; oldNewNameDictionary[oldName] = newName; if (targetElement == sourceElement) { var original = sourceElement.Instances.FirstOrDefault(item => item.Name == sourceInstance.Name); int newIndex = -1; if (original != null) { newIndex = sourceElement.Instances.IndexOf(original); } if (newIndex != -1) { targetElement.Instances.Insert(newIndex + 1, newInstance); } else { targetElement.Instances.Add(newInstance); } } else { targetElement.Instances.Add(newInstance); } } } foreach (var sourceInstance in instancesToCopy) { ElementSave sourceElement = sourceInstance.ParentContainer; var newInstance = newInstances.First(item => item.Name == oldNewNameDictionary[sourceInstance.Name]); if (targetElement != null) { StateSave stateSave = copiedState; StateSave targetState; // We now have to copy over the states if (targetElement != sourceElement) { if (sourceElement.States.Count != 1) { MessageBox.Show("Only the default state variables will be copied since the source and target elements differ."); } targetState = targetElement.DefaultState; } else { targetState = SelectedState.Self.SelectedStateSave ?? SelectedState.Self.SelectedElement.DefaultState; } // why reverse loop? for (int i = stateSave.Variables.Count - 1; i > -1; i--) { // We may have copied over a group of instances. If so // the copied state may have variables for multiple instances. // We only want to apply the variables that work for the selected // object. VariableSave sourceVariable = stateSave.Variables[i]; if (sourceVariable.SourceObject == sourceInstance.Name) { VariableSave copiedVariable = sourceVariable.Clone(); copiedVariable.Name = newInstance.Name + "." + copiedVariable.GetRootName(); var valueAsString = copiedVariable.Value as string; if (copiedVariable.GetRootName() == "Parent" && string.IsNullOrWhiteSpace(valueAsString) == false && oldNewNameDictionary.ContainsKey(valueAsString)) { // this is a parent and it may be attached to a copy, so update the value var newValue = oldNewNameDictionary[valueAsString]; copiedVariable.Value = newValue; } // We don't want to copy exposed variables. // If we did, the user would have 2 variables exposed with the same. copiedVariable.ExposedAsName = null; targetState.Variables.Add(copiedVariable); } } // Copy over the VariableLists too for (int i = stateSave.VariableLists.Count - 1; i > -1; i--) { VariableListSave sourceVariableList = stateSave.VariableLists[i]; if (sourceVariableList.SourceObject == sourceInstance.Name) { VariableListSave copiedList = sourceVariableList.Clone(); copiedList.Name = newInstance.Name + "." + copiedList.GetRootName(); targetState.VariableLists.Add(copiedList); } } // This used to be done here when we paste, but now we're // going to remove it when the cut happens - just like text // editors. Undo will handle this if we mess up. // bool shouldSaveSource = false; //if (mIsCtrlXCut) //{ // if (sourceElement.Instances.Contains(sourceInstance)) // { // // Not sure why we weren't just using // // ElementCommands here - maybe an oversight? // // This should improve things like // //sourceElement.Instances.Remove(sourceInstance); // ElementCommands.Self.RemoveInstance(sourceInstance, sourceElement); // shouldSaveSource = true; // } //} newInstance.ParentContainer = targetElement; // We need to call InstanceAdd before we select the new object - the Undo manager expects it // This includes before other managers refresh PluginManager.Self.InstanceAdd(targetElement, newInstance); } } WireframeObjectManager.Self.RefreshAll(true); GumCommands.Self.GuiCommands.RefreshElementTreeView(targetElement); GumCommands.Self.FileCommands.TryAutoSaveElement(targetElement); SelectedState.Self.SelectedInstances = newInstances; }