public static void RemoveNamedObject(NamedObjectSave namedObjectToRemove, bool performSave, bool updateUi, List <string> additionalFilesToRemove) { StringBuilder removalInformation = new StringBuilder(); // The additionalFilesToRemove is included for consistency with other methods. It may be used later // There are the following things that need to happen: // 1. Remove the NamedObject from the Glue project (GLUX) // 2. Remove any variables that use this NamedObject as their source // 3. Remove the named object from the GUI // 4. Update the variables for any NamedObjects that use this element containing this NamedObject // 5. Find any Elements that contain NamedObjects that are DefinedByBase - if so, see if we should remove those or make them not DefinedByBase // 6. Remove any events that tunnel into this. IElement element = namedObjectToRemove.GetContainer(); if (element != null) { if (!namedObjectToRemove.RemoveSelfFromNamedObjectList(element.NamedObjects)) { throw new ArgumentException(); } #region Remove all CustomVariables that reference the removed NamedObject for (int i = element.CustomVariables.Count - 1; i > -1; i--) { CustomVariable variable = element.CustomVariables[i]; if (variable.SourceObject == namedObjectToRemove.InstanceName) { removalInformation.AppendLine("Removed variable " + variable.ToString()); element.CustomVariables.RemoveAt(i); } } #endregion // Remove any events that use this for (int i = element.Events.Count - 1; i > -1; i--) { EventResponseSave ers = element.Events[i]; if (ers.SourceObject == namedObjectToRemove.InstanceName) { removalInformation.AppendLine("Removed event " + ers.ToString()); element.Events.RemoveAt(i); } } // Remove any objects that use this as a layer for (int i = 0; i < element.NamedObjects.Count; i++) { if (element.NamedObjects[i].LayerOn == namedObjectToRemove.InstanceName) { removalInformation.AppendLine("Removed the following object from the deleted Layer: " + element.NamedObjects[i].ToString()); element.NamedObjects[i].LayerOn = null; } } element.RefreshStatesToCustomVariables(); #region Ask the user what to do with all NamedObjects that are DefinedByBase List <IElement> derivedElements = new List <IElement>(); if (element is EntitySave) { derivedElements.AddRange(ObjectFinder.Self.GetAllEntitiesThatInheritFrom(element as EntitySave)); } else { derivedElements.AddRange(ObjectFinder.Self.GetAllScreensThatInheritFrom(element as ScreenSave)); } foreach (IElement derivedElement in derivedElements) { // At this point, namedObjectToRemove is already removed from the current Element, so this will only // return NamedObjects that exist in the derived. NamedObjectSave derivedNamedObject = derivedElement.GetNamedObjectRecursively(namedObjectToRemove.InstanceName); if (derivedNamedObject != null && derivedNamedObject != namedObjectToRemove && derivedNamedObject.DefinedByBase) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "What would you like to do with the object " + derivedNamedObject.ToString(); mbmb.AddButton("Keep it", DialogResult.OK); mbmb.AddButton("Delete it", DialogResult.Cancel); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); if (result == DialogResult.OK) { // Keep it derivedNamedObject.DefinedByBase = false; BaseElementTreeNode treeNode = GlueState.Self.Find.ElementTreeNode(derivedElement); if (updateUi) { treeNode.UpdateReferencedTreeNodes(); } CodeWriter.GenerateCode(derivedElement); } else { // Delete it RemoveNamedObject(derivedNamedObject, performSave, updateUi, additionalFilesToRemove); } } } #endregion var elementTreeNode = GlueState.Self.Find.ElementTreeNode(element); if (updateUi) { elementTreeNode.UpdateReferencedTreeNodes(); } CodeWriter.GenerateCode(element); if (element is EntitySave) { List <NamedObjectSave> entityNamedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(element.Name); foreach (NamedObjectSave nos in entityNamedObjects) { nos.UpdateCustomProperties(); } } } if (performSave) { GluxCommands.Self.SaveGlux(); } }
private void ReactToNamedObjectChangedInstanceName(NamedObjectSave namedObjectSave, object oldValueAsObject) { string oldValue = (string)oldValueAsObject; #region Fail checks string whyItIsntValid; NameVerifier.IsNamedObjectNameValid(namedObjectSave.InstanceName, out whyItIsntValid); if (!string.IsNullOrEmpty(whyItIsntValid)) { GlueGui.ShowMessageBox(whyItIsntValid); namedObjectSave.InstanceName = oldValue; } #endregion else { IElement currentElement = EditorLogic.CurrentElement; string baseObject = ((IElement)EditorLogic.CurrentElement).BaseObject; // See if the entity has a base and if the base contains this name if (!string.IsNullOrEmpty(baseObject)) { INamedObjectContainer baseNamedObjectContainer = ObjectFinder.Self.GetNamedObjectContainer(baseObject); NamedObjectSave baseNamedObject = baseNamedObjectContainer.GetNamedObjectRecursively(namedObjectSave.InstanceName); if (baseNamedObject != null) { if (baseNamedObject.SetByDerived) { // There is a base element that has an object with the same // name as the derived element. The derived doesn't have a same-named // object already, and the base is SetByDerived, so let's setup the derived // to use the base and notify the user. namedObjectSave.DefinedByBase = true; MessageBox.Show("This object has the same name as\n\n" + baseNamedObject.ToString() + "\n\nIt is SetByDerived, " + "so Glue will use this as the base object for the object " + namedObjectSave.InstanceName); } else { System.Windows.Forms.MessageBox.Show("A base object already has an object with this name"); namedObjectSave.InstanceName = oldValue; } } } if (currentElement != null) { // See if any named objects in this instance use this for tunneling foreach (CustomVariable customVariable in currentElement.CustomVariables) { if (!string.IsNullOrEmpty(customVariable.SourceObject) && customVariable.SourceObject == oldValue) { MessageBox.Show("Changing the variable " + customVariable.Name + " so it uses " + namedObjectSave.InstanceName + " instead of " + (string)oldValue); customVariable.SourceObject = namedObjectSave.InstanceName; } } // See if any events tunnel to this NOS foreach (EventResponseSave eventResponseSave in currentElement.Events) { if (!string.IsNullOrEmpty(eventResponseSave.SourceObject) && eventResponseSave.SourceObject == oldValue) { MessageBox.Show("Chaing the Event " + eventResponseSave.EventName + " so it uses " + namedObjectSave.InstanceName + " instead of " + oldValue); eventResponseSave.SourceObject = namedObjectSave.InstanceName; } } } // If this is a layer, see if any other NOS's use this as their Layer if (namedObjectSave.IsLayer) { List <NamedObjectSave> namedObjectList = EditorLogic.CurrentElement.NamedObjects; string oldLayerName = (string)oldValue; foreach (NamedObjectSave nos in namedObjectList) { nos.ReplaceLayerRecursively(oldLayerName, namedObjectSave.InstanceName); } } } }