private bool DeserializeGluxXmlInternal(string projectFileName, string glueProjectFile) { bool succeeded = true; try { ProjectManager.GlueProjectSave = GlueProjectSaveExtensions.Load(glueProjectFile); string errors; ProjectManager.GlueProjectSave.PostLoadInitialize(out errors); if (errors != null) { GlueGui.ShowMessageBox(errors); } } catch (Exception e) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "There was an error loading the .glux file. What would you like to do?"; mbmb.AddButton("Nothing - Glue will abort loading the project.", DialogResult.None); mbmb.AddButton("See the Exception", DialogResult.OK); mbmb.AddButton("Try loading again", DialogResult.Retry); mbmb.AddButton("Test for conflicts", DialogResult.Yes); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); mCurrentInitWindow.Close(); switch (result) { case DialogResult.None: // Do nothing; break; case DialogResult.OK: MessageBox.Show(e.ToString()); break; case DialogResult.Retry: LoadProject(projectFileName); break; case DialogResult.Yes: string text = FileManager.FromFileText(glueProjectFile); if (text.Contains("<<<")) { MessageBox.Show("There are conflicts in your GLUX file. You will need to use a merging " + "tool or text editor to resolve these conflicts."); } else { MessageBox.Show("No Subversion conflicts found in your GLUX."); } break; } succeeded = false; } return succeeded; }
void ContentPipelineChange(bool useContentPipeline, CurrentElementOrAll currentOrAll) { TextureProcessorOutputFormat? textureFormat = null; if (useContentPipeline) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "How should the texture formats be set?"; mbmb.AddButton("Set to DXT Compression", DialogResult.Yes); mbmb.AddButton("Set to Color", DialogResult.OK); mbmb.AddButton("Do nothing", DialogResult.No); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); switch (result) { case DialogResult.Yes: textureFormat = TextureProcessorOutputFormat.DxtCompressed; break; case DialogResult.OK: textureFormat = TextureProcessorOutputFormat.Color; break; case DialogResult.No: // do nothing, leave it to null break; } } InitializationWindow initWindow = new InitializationWindow(); initWindow.Show(MainGlueWindow.Self); initWindow.Message = "Performing Operation..."; List<ReferencedFileSave> allRfses = new List<ReferencedFileSave>(); if (currentOrAll == CurrentElementOrAll.CurrentElement) { IElement element = EditorLogic.CurrentElement; allRfses.AddRange(element.ReferencedFiles); } else { allRfses.AddRange(ObjectFinder.Self.GetAllReferencedFiles()); } int totalRfs = allRfses.Count; //int count = 0; initWindow.SubMessage = "Removing/adding files as appropriate"; Application.DoEvents(); foreach (ReferencedFileSave rfs in allRfses) { if (rfs.GetAssetTypeInfo() != null && rfs.GetAssetTypeInfo().MustBeAddedToContentPipeline) { rfs.UseContentPipeline = true; } else { rfs.UseContentPipeline = useContentPipeline; } } ContentPipelineHelper.ReactToUseContentPipelineChange(allRfses); if (useContentPipeline) { initWindow.SubMessage = "Updating texture formats"; Application.DoEvents(); foreach (ReferencedFileSave rfs in allRfses) { if (textureFormat.HasValue) { rfs.TextureFormat = textureFormat.Value; } ContentPipelineHelper.UpdateTextureFormatFor(rfs); } } initWindow.SubMessage = "Refreshing UI"; Application.DoEvents(); if (EditorLogic.CurrentElement != null) { GlueCommands.RefreshCommands.RefreshUiForSelectedElement(); } initWindow.SubMessage = "Generating Code"; Application.DoEvents(); if (currentOrAll == CurrentElementOrAll.CurrentElement) { GlueCommands.GenerateCodeCommands.GenerateCurrentElementCode(); } else { GlueCommands.GenerateCodeCommands.GenerateAllCode(); } GlueCommands.GluxCommands.SaveGlux(); GlueCommands.ProjectCommands.SaveProjects(); initWindow.Close(); }
private void CreateEntityTreeNodes() { //ProjectManager.GlueProjectSave.Entities[78].NamedObjects[9].UpdateCustomProperties(); // Let's make this faster. //foreach (EntitySave entity in ProjectManager.GlueProjectSave.Entities) // Actually, the contained functions may show popups, and if 2 simultaneous popups // are shown, one can cancel the other out and this can cause Glue to freeze. This means // we can't parallel foreah it //Parallel.ForEach(ProjectManager.GlueProjectSave.Entities, (entity) => foreach (EntitySave entity in ProjectManager.GlueProjectSave.Entities) { entity.UpdateCustomProperties(); entity.UpdateFromBaseType(); } for (int i = 0; i < ProjectManager.GlueProjectSave.Entities.Count; i++) { EntitySave entitySave = ProjectManager.GlueProjectSave.Entities[i]; // This is so fast that we no longer need to show the // user details - and not doing it will make things even faster //SetInitWindowText("Creating Entity: " + entitySave.Name); EntityTreeNode entityTreeNode = GlueState.Self.Find.EntityTreeNode(entitySave.Name); #region If there is no EntityTreeNode if (entityTreeNode == null) { // See if the file exists string fileToSearchFor = FileManager.RelativeDirectory + entitySave.Name + ".cs"; if (System.IO.File.Exists(fileToSearchFor)) { // If we got here that means there's probably not a build item for this file MessageBox.Show("The Glue project has the following Entity:\n" + entitySave.Name + "\n" + "but this file is not part of Visual Studio. This file may have been removed manually or " + "there may have been some saving error. You should close Glue, manually add this and the Generated file " + "to Visual Studio, then restart Glue."); MainGlueWindow.Self.HasErrorOccurred = true; } else { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "Could not find the file name\n\n" + fileToSearchFor + "\n\nwhich is used by the entity\n\n" + entitySave.Name + "\n\n" + "What would you like to do?"; mbmb.AddButton("Create a new custom code file", DialogResult.Yes); mbmb.AddButton("Delete this Entity", DialogResult.No); mbmb.AddButton("Do nothing. The Entity will not show up in Glue until this problem is fixed.", DialogResult.Cancel); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); switch (result) { case DialogResult.Yes: if (entityTreeNode == null) { entityTreeNode = ElementViewWindow.AddEntity(entitySave); } CodeWriter.GenerateAndAddElementCustomCode(entitySave); //entityTreeNode.GenerateCode(ProjectManager.EntityTemplateCode); break; case DialogResult.No: ProjectManager.GlueProjectSave.Entities.RemoveAt(i); i--; continue; //break; case DialogResult.Cancel: // do nothing continue; //break; } System.Windows.Forms.MessageBox.Show("Could not create the EntitySave for " + entitySave.Name + " because the following file doesn't exist\n\n" + fileToSearchFor); } //mGlueProjectSave.Entities.RemoveAt(i); //i--; } #endregion entityTreeNode.EntitySave = entitySave; CheckForMissingCustomFile(entityTreeNode); entityTreeNode.UpdateReferencedTreeNodes(performSave: false); // moved above //entityTreeNode.EntitySave.UpdateCustomProperties(); //entityTreeNode.EntitySave.UpdateFromBaseType(); } }
private bool ResolveDuplicateProjectEntry(bool wasChanged, ProjectItem buildItem) { #if GLUE MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "The item " + buildItem.UnevaluatedInclude + " is part of " + "the project twice. Glue does not support double-entries in a project. What would you like to do?"; mbmb.AddButton("Remove the duplicate entry and continue", System.Windows.Forms.DialogResult.OK); mbmb.AddButton("Remove the duplicate, but show me a list of all contained objects before removal", System.Windows.Forms.DialogResult.No); mbmb.AddButton("Cancel loading the project - this will throw an exception", System.Windows.Forms.DialogResult.Cancel); DialogResult result; if (GlueGui.TryShowDialog(mbmb, out result)) { switch (result) { case DialogResult.OK: mProject.RemoveItem(buildItem); break; case DialogResult.No: StringBuilder stringBuilder = new StringBuilder(); foreach (var item in mProject.AllEvaluatedItems) { stringBuilder.AppendLine(item.ItemType + " " + item.UnevaluatedInclude); } string whereToSave = FileManager.UserApplicationDataForThisApplication + "ProjectFileOutput.txt"; FileManager.SaveText(stringBuilder.ToString(), whereToSave); Process.Start(whereToSave); mProject.RemoveItem(buildItem); break; case DialogResult.Cancel: throw new Exception("Duplicate entries found: " + buildItem.ItemType + " " + buildItem.UnevaluatedInclude); } } else #endif { //mProject.EvaluatedItems.RemoveItemAt(i); mProject.RemoveItem(buildItem); } wasChanged = true; return wasChanged; }
private static void CheckForExistingFileOfSameName(string oldName, ReferencedFileSave fileSave, string newFileNameAbsolute, ref bool shouldMove, ref bool shouldContinue) { if (FileManager.FileExists(newFileNameAbsolute)) { string message = "The new file name already exists. What would you like to do?"; MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = message; mbmb.AddButton("Use existing file", DialogResult.Yes); mbmb.AddButton("Cancel the rename", DialogResult.Cancel); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); if (result == DialogResult.Cancel) { fileSave.SetNameNoCall(oldName); shouldContinue = false; } else if (result == DialogResult.Yes) { shouldMove = false; } } }
private void HandleChangedIsContainer(NamedObjectSave nos, IElement element) { if (nos.IsContainer) { var existingContainer = element.AllNamedObjects.FirstOrDefault( item => item.IsContainer && item != nos); bool succeeded = true; if (existingContainer != null) { succeeded = false; MessageBox.Show("The object " + existingContainer + " is already marked as IsContainer. " + "Two objects in the same element cannot be marked as Iscontainer"); } if (succeeded) { bool doesBaseMatch = !string.IsNullOrEmpty(element.BaseElement) && element.BaseElement == nos.SourceClassType; if (!doesBaseMatch) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); string containerType = element.BaseElement; if (string.IsNullOrEmpty(containerType)) { containerType = "<NONE>"; } mbmb.MessageText = "The object is of type " + nos.SourceClassType + " but the container is of type " + containerType + "\n\n" + "What would you like to do?"; mbmb.AddButton("Set the container's type to " + nos.SourceClassType, DialogResult.Yes); mbmb.AddButton("Nothing - game may not compile until this has been fixed", DialogResult.No); mbmb.AddButton("Set 'IsContainer' back to false", DialogResult.Cancel); var dialogResult = mbmb.ShowDialog(); if (dialogResult == DialogResult.Yes) { element.BaseObject = nos.SourceClassType; } else if (dialogResult == DialogResult.Cancel) { succeeded = false; } } } if(!succeeded) { nos.IsContainer = false; } } }
private void ReactToTextureAddressMode(NamedObjectSave namedObjectSave, object oldValue) { bool isSprite = namedObjectSave.SourceType == SourceType.FlatRedBallType && namedObjectSave.SourceClassType == "Sprite"; if(isSprite) { var addressModeVariable = namedObjectSave.GetCustomVariable("TextureAddressMode"); if (addressModeVariable != null && addressModeVariable.Value != null && ((TextureAddressMode)(addressModeVariable.Value) == TextureAddressMode.Wrap || (TextureAddressMode)(addressModeVariable.Value) == TextureAddressMode.Mirror)) { // How big is the texture? var textureVariable = namedObjectSave.GetCustomVariable("Texture"); if (textureVariable != null && textureVariable.Value != null) { string value = textureVariable.Value as string; var rfs = namedObjectSave.GetContainer().GetReferencedFileSaveByInstanceName(value); if (rfs != null) { var width = ImageHeader.GetDimensions( ProjectManager.MakeAbsolute(rfs.Name)).Width; var height = ImageHeader.GetDimensions( ProjectManager.MakeAbsolute(rfs.Name)).Height; string whatIsWrong = null; if (FlatRedBall.Math.MathFunctions.IsPowerOfTwo(width) == false) { whatIsWrong = "This Sprite's texture (" + textureVariable.Value + ") has a width of " + width + " but it should be a power of two to use " + addressModeVariable.Value + " TextureAddressMode"; } if (FlatRedBall.Math.MathFunctions.IsPowerOfTwo(height) == false) { whatIsWrong = "This Sprite's texture (" + textureVariable.Value + ") has a height of " + height + " but it should be a power of two to use " + addressModeVariable.Value + " TextureAddressMode"; } if(!string.IsNullOrEmpty(whatIsWrong)) { whatIsWrong += "\nWhat would you like to do?"; MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = whatIsWrong; mbmb.AddButton("Undo the change", DialogResult.Cancel); mbmb.AddButton("Keep the change (May cause runtime crashes)", DialogResult.Yes); var result = mbmb.ShowDialog(); if(result == DialogResult.Cancel) { addressModeVariable.Value = oldValue; } } } } } } }
public static bool TryAskToMoveFileRelativeToAnimationChainFile(ref string absoluteFileName, out string achxFolder) { bool shouldProceed = true; achxFolder = FileManager.GetDirectory(ProjectManager.Self.FileName); if (ShouldAskUserToCopyFile(absoluteFileName)) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "The selected file:\n\n" + absoluteFileName + "\n\nis not relative to the Animation Chain file. What would you like to do?"; mbmb.AddButton("Copy the file to the same folder as the Animation Chain", System.Windows.Forms.DialogResult.Yes); mbmb.AddButton("Keep the file where it is (this may limit the portability of the Animation Chain file)", System.Windows.Forms.DialogResult.No); DialogResult result = mbmb.ShowDialog(); if (result == DialogResult.Yes) { string destination = achxFolder + FileManager.RemovePath(absoluteFileName); try { System.IO.File.Copy(absoluteFileName, destination, true); absoluteFileName = destination; } catch (Exception e) { MessageBox.Show("Could not copy the file:\n" + e); } } else if (result == DialogResult.Cancel) { shouldProceed = false; } } return shouldProceed; }
private static void RemoveEntity(EntitySave entityToRemove, List<string> filesThatCouldBeRemoved) { List<NamedObjectSave> namedObjectsToRemove = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(entityToRemove.Name); DialogResult result = DialogResult.Yes; string message = null; if (namedObjectsToRemove.Count != 0) { message = "The Entity " + entityToRemove.ToString() + " is referenced by the following objects:"; for (int i = 0; i < namedObjectsToRemove.Count; i++) { message += "\n" + namedObjectsToRemove[i].ToString(); } } List<EntitySave> inheritingEntities = ObjectFinder.Self.GetAllEntitiesThatInheritFrom(entityToRemove); if (inheritingEntities.Count != 0) { message = "The Entity " + entityToRemove.ToString() + " is the base for the following Entities:"; for (int i = 0; i < inheritingEntities.Count; i++) { message += "\n" + inheritingEntities[i].ToString(); } } if (message != null) { message += "\n\nDo you really want to remove this Entity?"; result = MessageBox.Show(message, "Are you sure?", MessageBoxButtons.YesNo); } if (result == DialogResult.Yes) { for (int i = entityToRemove.NamedObjects.Count - 1; i > -1; i--) { NamedObjectSave nos = entityToRemove.NamedObjects[i]; ProjectManager.RemoveNamedObject(nos, false, false, null); } if (entityToRemove.CreatedByOtherEntities == true) { FactoryCodeGenerator.RemoveFactory(entityToRemove); } // We used to rely on RemoveUnreferencedFiles to do the removal of all RFS's // However, RemoveUnreferencedFiles looks for the file's container to remove it, // and by this point the entityToRemove has already been removed from the project. // So we'll manually remove the RFS's first before removing the entire entity for (int i = entityToRemove.ReferencedFiles.Count - 1; i > -1; i--) { GluxCommands.Self.RemoveReferencedFile(entityToRemove.ReferencedFiles[i], filesThatCouldBeRemoved); } ProjectManager.GlueProjectSave.Entities.Remove(entityToRemove); RemoveUnreferencedFiles(entityToRemove, filesThatCouldBeRemoved); for (int i = 0; i < namedObjectsToRemove.Count; i++) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); NamedObjectSave nos = namedObjectsToRemove[i]; mbmb.MessageText = "What would you like to do with the object\n\n" + nos.ToString(); mbmb.AddButton("Remove this Object", DialogResult.OK); mbmb.AddButton("Keep this Object (the reference will be invalid)", DialogResult.Cancel); DialogResult namedObjectRemovalResult = mbmb.ShowDialog(); if (namedObjectRemovalResult == DialogResult.OK) { ProjectManager.RemoveNamedObject(nos, false, true, filesThatCouldBeRemoved); } } for (int i = 0; i < inheritingEntities.Count; i++) { EntitySave inheritingEntity = inheritingEntities[i]; DialogResult resetInheritance = MessageBox.Show("Reset the inheritance for " + inheritingEntity.Name + "?", "Reset Inheritance?", MessageBoxButtons.YesNo); if (resetInheritance == DialogResult.Yes) { inheritingEntity.BaseEntity = ""; CodeWriter.GenerateCode(inheritingEntity); } } ElementViewWindow.RemoveEntity(entityToRemove); ProjectManager.RemoveCodeFilesForElement(filesThatCouldBeRemoved, entityToRemove); ProjectManager.SaveProjects(); GluxCommands.Self.SaveGlux(); } }
private static void ShowErrorMessageBox(ref bool hasUserCancelled, ref string zipToUnpack, string message) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = message; mbmb.AddButton("Look for the file in the default location", DialogResult.Yes); mbmb.AddButton("Select a .zip file to use", DialogResult.OK); mbmb.AddButton("Nothing - don't create a project", DialogResult.Cancel); var dialogResult = mbmb.ShowDialog(); if (dialogResult == DialogResult.Yes) { // do nothing, it'll just look in the default location.... } else if (dialogResult == DialogResult.OK) { OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.InitialDirectory = "c:\\"; fileDialog.Filter = "Zipped FRB template (*.zip)|*.zip"; fileDialog.RestoreDirectory = true; if (fileDialog.ShowDialog() == DialogResult.OK) { zipToUnpack = fileDialog.FileName; } } else if (dialogResult == DialogResult.Cancel) { hasUserCancelled = true; } }
internal static NamedObjectSave CreateNewNamedObjectInElement(IElement elementToCreateIn, EntitySave blueprintEntity, bool createList = false) { if (elementToCreateIn is EntitySave && ((EntitySave)elementToCreateIn).ImplementsIVisible && !blueprintEntity.ImplementsIVisible) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "The Entity\n\n" + blueprintEntity + "\n\nDoes not Implement IVisible, but the Entity it is being dropped in does. " + "What would you like to do?"; mbmb.AddButton("Make " + blueprintEntity.Name + " implement IVisible", DialogResult.OK); mbmb.AddButton("Nothing (your code will not compile until this problem is resolved manually)", DialogResult.Cancel); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); if (result == DialogResult.OK) { blueprintEntity.ImplementsIVisible = true; CodeGeneratorIElement.GenerateElementDerivedAndReferenced(blueprintEntity); } } BaseElementTreeNode elementTreeNode = GlueState.Self.Find.ElementTreeNode(elementToCreateIn); //EntityTreeNode entityTreeNode = // ElementViewWindow.GetEntityTreeNode(entityToCreateIn); NamedObjectSave newNamedObject = new NamedObjectSave(); // We'll add "List" or "Instance" below string newName = FileManager.RemovePath(blueprintEntity.Name); #region Set the source type properties for the new NamedObject if (createList) { newName += "List"; newNamedObject.SourceType = SourceType.FlatRedBallType; newNamedObject.SourceClassType = "PositionedObjectList<T>"; newNamedObject.SourceClassGenericType = blueprintEntity.Name; newNamedObject.UpdateCustomProperties(); } else { newName += "Instance"; newNamedObject.SourceType = SourceType.Entity; newNamedObject.SourceClassType = blueprintEntity.Name; newNamedObject.UpdateCustomProperties(); } #endregion #region Set the name for the new NamedObject // get an acceptable name for the new object if (elementToCreateIn.GetNamedObjectRecursively(newName) != null) { newName += "2"; } while (elementToCreateIn.GetNamedObjectRecursively(newName) != null) { newName = StringFunctions.IncrementNumberAtEnd(newName); } newNamedObject.InstanceName = newName; #endregion // We need to add to managers here. Why? Because normally when the type of a NamedObject is changed, // the PropertyGrid handles setting whether it should be added or not. But in this case, we're not changing // the type of the new NamedObject through the PropertyGrid - instead it's being set programatically to be an // Entity. So, we should add to managers programatically since the PropertyGrid won't do it for us. // Update December 11, 2011 // AddToManagers defaults to // true on new NamedObjectSaves // so there's no need to explicitly // set it to true here. //newNamedObject.AddToManagers = true; NamedObjectSaveExtensionMethodsGlue.AddNewNamedObjectToElementTreeNode(elementTreeNode, newNamedObject, true); return newNamedObject; }
private static DialogResult AskToReplaceOrRename() { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.AddButton("Replace original file", DialogResult.Yes); mbmb.AddButton("Rename and reference renamed", DialogResult.No); mbmb.MessageText = "What would you like to do with the resized file?"; return mbmb.ShowDialog(); }
private static DialogResult AskWhatUserWantsToDo() { MultiButtonMessageBox mbmb; mbmb = new MultiButtonMessageBox(); string message = "What would you like to do?"; mbmb.MessageText = message; mbmb.AddButton("Pad to power of two", System.Windows.Forms.DialogResult.OK); mbmb.AddButton("Cancel", System.Windows.Forms.DialogResult.Cancel); return mbmb.ShowDialog(); }
public static bool UpdateNamedObjectsFromBaseType(INamedObjectContainer namedObjectContainer) { bool haveChangesOccurred = false; List<NamedObjectSave> referencedObjectsBeforeUpdate = new List<NamedObjectSave>(); for (int i = 0; i < namedObjectContainer.NamedObjects.Count; i++) { if (namedObjectContainer.NamedObjects[i].DefinedByBase) { referencedObjectsBeforeUpdate.Add(namedObjectContainer.NamedObjects[i]); } } List<NamedObjectSave> namedObjectsSetByDerived = new List<NamedObjectSave>(); List<NamedObjectSave> namedObjectsExposedInDerived = new List<NamedObjectSave>(); List<INamedObjectContainer> baseElements = new List<INamedObjectContainer>(); // June 1, 2011: // The following code // was using AddRange instead // of manually looping, but this // is only possible in .NET 4.0, and // GlueView still uses 3.1. // July 24, 2011 // Before today, this // code would loop through // all base Entities and search // for SetByDerived properties in // any NamedObjectSave. This caused // bugs. Basically if you had 3 Elements // in an inheritance chain and the one at the // very base defined a NOS to be SetByDerived, then // anything that inherited directly from the base should // be forced to define it. If it does, then the 3rd Element // in the inheritance chain shouldn't have to define it, but before // to day it did. This caused a lot of problems including generated // code creating the element twice. if (namedObjectContainer is EntitySave) { if (!string.IsNullOrEmpty(namedObjectContainer.BaseObject)) { baseElements.Add(ObjectFinder.Self.GetIElement(namedObjectContainer.BaseObject)); } //List<EntitySave> allBase = ((EntitySave)namedObjectContainer).GetAllBaseEntities(); //foreach (EntitySave baseEntitySave in allBase) //{ // baseElements.Add(baseEntitySave); //} } else { if (!string.IsNullOrEmpty(namedObjectContainer.BaseObject)) { baseElements.Add(ObjectFinder.Self.GetIElement(namedObjectContainer.BaseObject)); } //List<ScreenSave> allBase = ((ScreenSave)namedObjectContainer).GetAllBaseScreens(); //foreach (ScreenSave baseScreenSave in allBase) //{ // baseElements.Add(baseScreenSave); //} } foreach (INamedObjectContainer baseNamedObjectContainer in baseElements) { if (baseNamedObjectContainer != null) { namedObjectsSetByDerived.AddRange(baseNamedObjectContainer.GetNamedObjectsToBeSetByDerived()); namedObjectsExposedInDerived.AddRange(baseNamedObjectContainer.GetNamedObjectsToBeExposedInDerived()); } } #region See if there are any objects to be removed from the derived. for (int i = referencedObjectsBeforeUpdate.Count - 1; i > -1; i--) { bool contains = false; for (int j = 0; j < namedObjectsSetByDerived.Count; j++) { if (referencedObjectsBeforeUpdate[i].InstanceName == namedObjectsSetByDerived[j].InstanceName && referencedObjectsBeforeUpdate[i].DefinedByBase) { contains = true; break; } } for (int j = 0; j < namedObjectsExposedInDerived.Count; j++) { if (referencedObjectsBeforeUpdate[i].InstanceName == namedObjectsExposedInDerived[j].InstanceName && referencedObjectsBeforeUpdate[i].DefinedByBase) { contains = true; break; } } if (!contains) { NamedObjectSave nos = referencedObjectsBeforeUpdate[i]; string message = "The following object is marked as \"defined by base\" but it is not contained in " + "any base elements\n\n" + nos.ToString() + "\n\nWhat would you like to do?"; MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = message; mbmb.AddButton("Remove " + nos.ToString(), DialogResult.Yes); mbmb.AddButton("Keep it, make it not \"defined by base\"", DialogResult.No); DialogResult result = mbmb.ShowDialog(); if (result == DialogResult.Yes) { // We got a NamedObject we should remove namedObjectContainer.NamedObjects.Remove(nos); referencedObjectsBeforeUpdate.RemoveAt(i); } else { nos.DefinedByBase = false; nos.InstantiatedByBase = false; } haveChangesOccurred = true; } } #endregion #region Next, see if there are any objects to be added for (int i = 0; i < namedObjectsSetByDerived.Count; i++) { NamedObjectSave namedObjectSetByDerived = namedObjectsSetByDerived[i]; NamedObjectSave matchingDefinedByBase = null;// contains = false; for (int j = 0; j < referencedObjectsBeforeUpdate.Count; j++) { if (referencedObjectsBeforeUpdate[j].InstanceName == namedObjectSetByDerived.InstanceName && referencedObjectsBeforeUpdate[j].DefinedByBase) { matchingDefinedByBase = referencedObjectsBeforeUpdate[j]; break; } } if (matchingDefinedByBase == null) { AddSetByDerivedNos(namedObjectContainer, namedObjectSetByDerived, false); } else { MatchDerivedToBase(namedObjectSetByDerived, matchingDefinedByBase); } } for (int i = 0; i < namedObjectsExposedInDerived.Count; i++) { NamedObjectSave namedObjectSetByDerived = namedObjectsExposedInDerived[i]; NamedObjectSave matchingDefinedByBase = null;// contains = false; for (int j = 0; j < referencedObjectsBeforeUpdate.Count; j++) { if (referencedObjectsBeforeUpdate[j].InstanceName == namedObjectSetByDerived.InstanceName && referencedObjectsBeforeUpdate[j].DefinedByBase) { matchingDefinedByBase = referencedObjectsBeforeUpdate[j]; break; } } if (matchingDefinedByBase == null) { AddSetByDerivedNos(namedObjectContainer, namedObjectSetByDerived, true); } else { MatchDerivedToBase(namedObjectSetByDerived, matchingDefinedByBase); } } #endregion return haveChangesOccurred; }
private void CheckForMissingCustomFile(BaseElementTreeNode baseElementTreeNode) { if (baseElementTreeNode != null) { IElement element = baseElementTreeNode.SaveObjectAsElement; string fileToSearchFor = FileManager.RelativeDirectory + element.Name + ".cs"; if (!System.IO.File.Exists(fileToSearchFor)) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "The following file is missing\n\n" + fileToSearchFor + "\n\nwhich is used by\n\n" + element.ToString() + "\n\nWhat would you like to do?"; mbmb.AddButton("Re-create an empty custom code file", DialogResult.OK); mbmb.AddButton("Ignore this problem", DialogResult.Cancel); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); switch (result) { case DialogResult.OK: CodeWriter.GenerateAndAddElementCustomCode(element); break; case DialogResult.Cancel: // Ignore, do nothing break; } } } }
private static void AskToRemoveCustomVariablesWithoutState(IElement element) { for(int i = 0; i < element.CustomVariables.Count; i++) { CustomVariable variable = element.CustomVariables[i]; if (CustomVariableHelper.IsStateMissingFor(variable, element)) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "The variable\n" + variable + "\nno longer has any states associated with it. What would you like to do?"; mbmb.AddButton("Remove the variable.", DialogResult.OK); mbmb.AddButton("Nothing (project may not run until this is fixed)", DialogResult.Cancel); if (mbmb.ShowDialog() == DialogResult.OK) { element.CustomVariables.RemoveAt(i); i--; } } } }
void HandleTextureChanged(object sender, MemberChangeArgs memberChangeArgs) { // Justin has reported a bug here. I don't know what is going on, so I'm going to spit out the error to a message box try { string fullFileName = memberChangeArgs.Value as string; string emitterDirectory = FileManager.GetDirectory(ProjectManager.Self.FileName); if (FileManager.IsRelative(fullFileName)) { // This file is relative. // This means that the user // typed in a value rather than // using the file window. We should // assume that the file is relative to // the emitter. fullFileName = emitterDirectory + fullFileName; } if (!FileManager.IsRelativeTo(fullFileName, emitterDirectory)) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "The selected file:\n\n" + fullFileName + "\n\nis not relative to the Emitter file. What would you like to do?"; mbmb.AddButton("Copy the file to the same folder as the Emitter file", System.Windows.Forms.DialogResult.Yes); mbmb.AddButton("Keep the file where it is (this may limit the portability of the Emitter file)", System.Windows.Forms.DialogResult.No); DialogResult result = mbmb.ShowDialog(); if (result == DialogResult.Yes) { string destination = emitterDirectory + FileManager.RemovePath(fullFileName); try { System.IO.File.Copy(fullFileName, destination, true); fullFileName = destination; } catch (Exception e) { MessageBox.Show("Could not copy the file:\n" + e); } } } string relativeFileName = FileManager.MakeRelative(fullFileName, emitterDirectory); SettingsSaveInstance.Texture = relativeFileName; } catch (Exception e) { MessageBox.Show(e.ToString()); } }
private static void AskToPreserveVariables(EntitySave entitySave, List<CustomVariable> variablesBefore) { foreach (CustomVariable oldVariable in variablesBefore) { if (entitySave.GetCustomVariableRecursively(oldVariable.Name) == null) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); string message = "The variable\n\n" + oldVariable.ToString() + "\n\nIs no longer part of the Entity. What do you want to do?"; mbmb.MessageText = message; mbmb.AddButton("Add a new variable with the same name and type to " + entitySave.Name, DialogResult.Yes); mbmb.AddButton("Nothing - the variable will go away", DialogResult.No); DialogResult result = mbmb.ShowDialog(); if (result == DialogResult.Yes) { CustomVariable newVariable = new CustomVariable(); newVariable.Type = oldVariable.Type; newVariable.Name = oldVariable.Name; newVariable.DefaultValue = oldVariable.DefaultValue; newVariable.SourceObject = oldVariable.SourceObject; newVariable.SourceObjectProperty = oldVariable.SourceObjectProperty; newVariable.Properties = new List<PropertySave>(); newVariable.Properties.AddRange(oldVariable.Properties); newVariable.HasAccompanyingVelocityProperty = oldVariable.HasAccompanyingVelocityProperty; newVariable.CreatesEvent = oldVariable.CreatesEvent; newVariable.IsShared = oldVariable.IsShared; if (!string.IsNullOrEmpty(oldVariable.OverridingPropertyType)) { newVariable.OverridingPropertyType = oldVariable.OverridingPropertyType; newVariable.TypeConverter = oldVariable.TypeConverter; } newVariable.CreatesEvent = oldVariable.CreatesEvent; entitySave.CustomVariables.Add(newVariable); } } } }
private void ReactToChangedNosSourceName(NamedObjectSave namedObjectSave, string oldValue) { IElement container = EditorLogic.CurrentElement; if (!string.IsNullOrEmpty(container.BaseElement) && !string.IsNullOrEmpty(namedObjectSave.InstanceType)) { IElement baseElement = ObjectFinder.Self.GetIElement(container.BaseElement); NamedObjectSave namedObjectInBase = baseElement.GetNamedObjectRecursively(namedObjectSave.InstanceName); if (namedObjectInBase == null) { // This is not a valid setup - what do we do here? } else { if (namedObjectInBase.InstanceType != namedObjectSave.InstanceType) { if (string.IsNullOrEmpty(namedObjectInBase.InstanceType)) { string message = "This object has type of " + namedObjectSave.InstanceType + " but the base object in " + baseElement.ToString() + " is untyped. What would you like to do?"; MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = message; mbmb.AddButton("Change " + namedObjectInBase.InstanceName + " to " + namedObjectSave.InstanceType + " in " + baseElement.ToString(), DialogResult.Yes); mbmb.AddButton("Do nothing (your project will likely not compile so you will need to fix this manually)", DialogResult.No); DialogResult result = mbmb.ShowDialog(); if (result == DialogResult.Yes) { switch (namedObjectInBase.SourceType) { case SourceType.File: // The base needs to be a FlatRedBallType namedObjectInBase.SourceType = SourceType.FlatRedBallType; namedObjectInBase.SourceClassType = namedObjectSave.InstanceType; break; case SourceType.FlatRedBallType: namedObjectInBase.SourceType = SourceType.FlatRedBallType; namedObjectInBase.SourceClassType = namedObjectSave.SourceClassType; break; case SourceType.Entity: namedObjectInBase.SourceType = SourceType.Entity; namedObjectInBase.SourceClassType = namedObjectSave.SourceClassType; break; } namedObjectInBase.UpdateCustomProperties(); CodeWriter.GenerateCode(baseElement); } } else { string message = "This object is of type " + namedObjectSave.InstanceType + " but the base " + "object is of type " + namedObjectInBase.InstanceType + ""; MessageBox.Show(message); namedObjectSave.SourceName = oldValue; } } } } }
private static void ReactToChangedImplementsIVisible(object oldValue, EntitySave entitySave) { #region If the user turned IVisible off, see if there is a "Visible" Exposed Variable if (((bool)oldValue) == true) { CustomVariable variableToRemove = entitySave.GetCustomVariable("Visible"); if (variableToRemove != null) { List<string> throwawayList = new List<string>(); MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "This entity has a \"Visible\" variable exposed. This variable is no longer valid. What would you like to do?"; mbmb.AddButton("Remove this variable", DialogResult.Yes); mbmb.AddButton("Keep this as a non-functional Variable (it will no longer control the object's visibility)", DialogResult.No); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); if (result == DialogResult.Yes) { ProjectManager.RemoveCustomVariable(variableToRemove, throwawayList); } else { // No need to do anything } } } #endregion #region If the user turned IVisible on, see if there are any NamedObjectSaves that reference Elements that are not IVisible if (entitySave.ImplementsIVisible) { foreach (NamedObjectSave nos in entitySave.AllNamedObjects) { if (nos.SourceType == SourceType.Entity || nos.IsList) { EntitySave nosEntitySave = null; if (nos.SourceType == SourceType.Entity) { nosEntitySave = ObjectFinder.Self.GetEntitySave(nos.SourceClassType); } else { nosEntitySave = ObjectFinder.Self.GetEntitySave(nos.SourceClassGenericType); } if (nosEntitySave != null && nosEntitySave.ImplementsIVisible == false) { MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = entitySave + " implements IVisible, but its object " + nos + " does not. Would would you like to do?"; mbmb.AddButton("Make " + nosEntitySave + " implement IVisible", DialogResult.Yes); mbmb.AddButton("Ignore " + nos + " when setting Visible on " + entitySave, DialogResult.No); mbmb.AddButton("Do nothing - this will likely cause compile errors so this must be fixed manually", DialogResult.Cancel); DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self); if (result == DialogResult.Yes) { nosEntitySave.ImplementsIVisible = true; CodeGeneratorIElement.GenerateElementDerivedAndReferenced(nosEntitySave); } else if (result == DialogResult.No) { nos.IncludeInIVisible = false; } else if (result == DialogResult.Cancel) { // do nothing - the user better fix this! } } } } } #endregion #region If it's a ScrollableEntityList, then the item it's using must also be an IVisible if (entitySave.ImplementsIVisible && entitySave.IsScrollableEntityList && !string.IsNullOrEmpty(entitySave.ItemType)) { EntitySave itemTypeAsEntity = ObjectFinder.Self.GetEntitySave(entitySave.ItemType); if (itemTypeAsEntity != null && itemTypeAsEntity.ImplementsIVisible == false) { MessageBox.Show("The item type " + itemTypeAsEntity.ToString() + " must also implement IVisible. Glue will do this now"); itemTypeAsEntity.ImplementsIVisible = true; // Gotta regen this thing var entityForItem = ObjectFinder.Self.GetIElement(entitySave.ItemType); CodeWriter.GenerateCode(entityForItem); } } #endregion }
public void RemoveReferencedFile(ReferencedFileSave referencedFileToRemove, List<string> additionalFilesToRemove, bool regenerateCode) { // There are some things that need to happen: // 1. Remove the ReferencedFileSave from the Glue project (GLUX) // 2. Remove the GUI item // 3. Remove the item from the Visual Studio project. #region Remove the file from the current Screen or Entity if there is a current Screen or Entity IElement container = referencedFileToRemove.GetContainer(); if (container != null) { // The referenced file better be a globally referenced file if (!container.ReferencedFiles.Contains(referencedFileToRemove)) { throw new ArgumentException(); } else { container.ReferencedFiles.Remove(referencedFileToRemove); } // Ask about any NamedObjects that reference this file. for (int i = container.NamedObjects.Count - 1; i > -1; i--) { var nos = container.NamedObjects[i]; if (nos.SourceType == SourceType.File && nos.SourceFile == referencedFileToRemove.Name) { MainGlueWindow.Self.Invoke(() => { // Ask the user what to do here - remove it? Keep it and not compile? MultiButtonMessageBox mbmb = new MultiButtonMessageBox(); mbmb.MessageText = "The object\n" + nos.ToString() + "\nreferences the file\n" + referencedFileToRemove.Name + "\nWhat would you like to do?"; mbmb.AddButton("Remove this object", DialogResult.Yes); mbmb.AddButton("Keep it (object will not be valid until changed)", DialogResult.No); var result = mbmb.ShowDialog(); if (result == DialogResult.Yes) { container.NamedObjects.RemoveAt(i); } }); } nos.ResetVariablesReferencing(referencedFileToRemove); } MainGlueWindow.Self.Invoke(() => { if (EditorLogic.CurrentScreenTreeNode != null) { EditorLogic.CurrentScreenTreeNode.UpdateReferencedTreeNodes(); } else if (EditorLogic.CurrentEntityTreeNode != null) { EditorLogic.CurrentEntityTreeNode.UpdateReferencedTreeNodes(false); } if (regenerateCode) { ElementViewWindow.GenerateSelectedElementCode(); } }); } #endregion #region else, the file is likely part of the GlobalContentFile else { ProjectManager.GlueProjectSave.GlobalFiles.Remove(referencedFileToRemove); ProjectManager.GlueProjectSave.GlobalContentHasChanged = true; // Much faster to just remove the tree node. This was done // to reuse code and make things reactive, but this has gotten // slow on bigger projects. //ElementViewWindow.UpdateGlobalContentTreeNodes(false); // don't save here because projects will get saved below Action refreshUiAction = () => { TreeNode treeNode = GlueState.Self.Find.ReferencedFileSaveTreeNode(referencedFileToRemove); if (treeNode.Tag != referencedFileToRemove) { throw new Exception("Error removing the tree node - the selected tree node doesn't reference the file being removed"); } treeNode.Parent.Nodes.Remove(treeNode); }; MainGlueWindow.Self.Invoke((MethodInvoker)delegate { refreshUiAction(); } ); ContentLoadWriter.UpdateLoadGlobalContentCode(); List<IElement> elements = ObjectFinder.Self.GetAllElementsReferencingFile(referencedFileToRemove.Name); foreach (IElement element in elements) { if (regenerateCode) { CodeWriter.GenerateCode(element); } } } #endregion // November 10, 2015 // I feel like this may // have been old code before // we had full dependency tracking // in Glue. This file should only be // removed from the project if nothing // else references it, including no entities. // This code does just entities/screens/global // content, but doesn't check the full dependency // tree. I think we can just remove it and depend on // the code below. // Actually, removing this seems to cause problems - files // that should be removed aren't. So instead we'll chnage the // call to use the dependency tree: // replace: List<string> referencedFiles = GlueCommands.Self.FileCommands.GetAllReferencedFileNames().Select(item=>item.ToLowerInvariant()).ToList(); string absoluteToLower = GlueCommands.Self.GetAbsoluteFileName(referencedFileToRemove).ToLowerInvariant(); string relativeToProject = FileManager.MakeRelative(absoluteToLower, GlueState.Self.ContentDirectory); bool isReferencedByOtherContent = referencedFiles.Contains(relativeToProject); if (isReferencedByOtherContent == false) { additionalFilesToRemove.Add(referencedFileToRemove.GetRelativePath()); string itemName = referencedFileToRemove.GetRelativePath(); string absoluteName = ProjectManager.MakeAbsolute(referencedFileToRemove.Name, true); // I don't know why we were removing the file from the ProjectBase - it should // be from the Content project //ProjectManager.RemoveItemFromProject(ProjectManager.ProjectBase, itemName); ProjectManager.RemoveItemFromProject(ProjectManager.ProjectBase.ContentProject, itemName, performSave: false); foreach (ProjectBase syncedProject in ProjectManager.SyncedProjects) { ProjectManager.RemoveItemFromProject(syncedProject.ContentProject, absoluteName); } } if (ProjectManager.IsContent(referencedFileToRemove.GetRelativePath())) { UnreferencedFilesManager.Self.RefreshUnreferencedFiles(false); foreach (var file in UnreferencedFilesManager.LastAddedUnreferencedFiles) { additionalFilesToRemove.Add(file.FilePath); } } ReactToRemovalIfCsv(referencedFileToRemove, additionalFilesToRemove); GluxCommands.Self.SaveGlux(); }
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 if (element is ScreenSave) { ScreenTreeNode stn = GlueState.Self.Find.ScreenTreeNode(element as ScreenSave); if (updateUi) { stn.UpdateReferencedTreeNodes(); } CodeWriter.GenerateCode(element); } else { EntityTreeNode etn = GlueState.Self.Find.EntityTreeNode(element as EntitySave); if (updateUi) { etn.UpdateReferencedTreeNodes(); } CodeWriter.GenerateCode(element); List<NamedObjectSave> entityNamedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(element.Name); foreach (NamedObjectSave nos in entityNamedObjects) { nos.UpdateCustomProperties(); } } } if (performSave) { GluxCommands.Self.SaveGlux(); } }