diff --git a/ActionBar/PrinterSelector.cs b/ActionBar/PrinterSelector.cs index bbdff22a3..100d19d64 100644 --- a/ActionBar/PrinterSelector.cs +++ b/ActionBar/PrinterSelector.cs @@ -52,9 +52,9 @@ namespace MatterHackers.MatterControl this.AddItem(printer.Name, printer.Id.ToString()); } - if(ActiveSliceSettings.Instance != null) + if (ActiveSliceSettings.Instance != null) { - this.SelectedValue = ActiveSliceSettings.Instance.Id(); + this.SelectedValue = ActiveSliceSettings.Instance.ID; } ImageBuffer plusImage = StaticData.Instance.LoadIcon("icon_plus.png", 32, 32); @@ -62,18 +62,18 @@ namespace MatterHackers.MatterControl this.SelectionChanged += (s, e) => { - int printerID; - if (int.TryParse(this.SelectedValue, out printerID)) + string printerID = this.SelectedValue; + if (printerID == "new") { - ActiveSliceSettings.SwitchToProfile(printerID); - } - else if(this.SelectedValue == "new") - { - if(AddPrinter != null) + if (AddPrinter != null) { UiThread.RunOnIdle(() => AddPrinter(this, null)); } } + else + { + ActiveSliceSettings.SwitchToProfile(printerID); + } }; } } diff --git a/DataStorage/Classic/ClassicSqlitePrinterProfiles.cs b/DataStorage/Classic/ClassicSqlitePrinterProfiles.cs index 48b7f3209..17004d62c 100644 --- a/DataStorage/Classic/ClassicSqlitePrinterProfiles.cs +++ b/DataStorage/Classic/ClassicSqlitePrinterProfiles.cs @@ -86,8 +86,9 @@ namespace MatterHackers.MatterControl.DataStorage.ClassicDB LoadQualitySettings(layeredProfile, printer); LoadMaterialSettings(layeredProfile, printer); + layeredProfile.ID = printer.Id.ToString(); + layeredProfile.UserLayer["MatterControl.PrinterName"] = printer.Name ?? ""; - layeredProfile.UserLayer["MatterControl.PrinterID"] = printer.Id.ToString(); layeredProfile.UserLayer["MatterControl.Make"] = printer.Make ?? ""; layeredProfile.UserLayer["MatterControl.Model"] = printer.Model ?? ""; layeredProfile.UserLayer["MatterControl.BaudRate"] = printer.BaudRate ?? ""; @@ -133,6 +134,7 @@ namespace MatterHackers.MatterControl.DataStorage.ClassicDB // TODO: Where can we find CalibrationFiiles in the current model? //layeredProfile.SetActiveValue("MatterControl.CalibrationFiles", printer.Make); + layeredProfile.ID = printer.Id.ToString(); string fullProfilePath = Path.Combine(profilePath, printer.Id + ".json"); File.WriteAllText(fullProfilePath, JsonConvert.SerializeObject(layeredProfile, Formatting.Indented)); } diff --git a/PrinterCommunication/PrinterConnectionAndCommunication.cs b/PrinterCommunication/PrinterConnectionAndCommunication.cs index 6b89067cc..2cfb71439 100644 --- a/PrinterCommunication/PrinterConnectionAndCommunication.cs +++ b/PrinterCommunication/PrinterConnectionAndCommunication.cs @@ -2491,7 +2491,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication // TODO: Fix printerItemID int requirement activePrintTask = new PrintTask(); activePrintTask.PrintStart = DateTime.Now; - activePrintTask.PrinterId = this.ActivePrinter.Id().GetHashCode(); + activePrintTask.PrinterId = this.ActivePrinter.ID.GetHashCode(); activePrintTask.PrintName = ActivePrintItem.PrintItem.Name; activePrintTask.PrintItemId = ActivePrintItem.PrintItem.Id; activePrintTask.PrintingGCodeFileName = ActivePrintItem.GetGCodePathAndFileName(); diff --git a/PrinterControls/PrinterConnections/BaseConnectionWidget.cs b/PrinterControls/PrinterConnections/BaseConnectionWidget.cs index 29b548eef..35f23342e 100644 --- a/PrinterControls/PrinterConnections/BaseConnectionWidget.cs +++ b/PrinterControls/PrinterConnections/BaseConnectionWidget.cs @@ -264,7 +264,7 @@ namespace MatterHackers.MatterControl.PrinterControls.PrinterConnections BaudRate = settings.BaudRate(), ComPort = settings.ComPort(), DriverType = settings.DriverType(), - Id = settings.Id(), + Id = settings.ID, Name = settings.Name() }; } diff --git a/PrinterControls/PrinterConnections/SetupConnectionWidgetBase.cs b/PrinterControls/PrinterConnections/SetupConnectionWidgetBase.cs index 9896a8c24..40dcb01f4 100644 --- a/PrinterControls/PrinterConnections/SetupConnectionWidgetBase.cs +++ b/PrinterControls/PrinterConnections/SetupConnectionWidgetBase.cs @@ -72,7 +72,6 @@ namespace MatterHackers.MatterControl.PrinterControls.PrinterConnections settings.SetBaudRate(ActivePrinter.BaudRate); settings.SetComPort(ActivePrinter.ComPort); settings.SetDriverType(ActivePrinter.DriverType); - settings.SetId(ActivePrinter.Id); settings.SetName(ActivePrinter.Name); }); diff --git a/SlicerConfiguration/Settings/ActiveSliceSettings.cs b/SlicerConfiguration/Settings/ActiveSliceSettings.cs index 88fd09875..814364008 100644 --- a/SlicerConfiguration/Settings/ActiveSliceSettings.cs +++ b/SlicerConfiguration/Settings/ActiveSliceSettings.cs @@ -120,7 +120,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration BaudRate = profile.BaudRate(), ComPort = profile.ComPort(), DriverType = profile.DriverType(), - Id = profile.Id(), + Id = profile.ID, Make = profile.Make, Model = profile.Model, Name = profile.Name(), @@ -193,11 +193,11 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } - internal static void SwitchToProfile(int id) + internal static void SwitchToProfile(string printerID) { - var profile = LoadProfile(id); + var profile = LoadProfile(printerID); - UserSettings.Instance.set("ActiveProfileID", id.ToString()); + UserSettings.Instance.set("ActiveProfileID", printerID); if (profile != null) { @@ -205,16 +205,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } - internal static SettingsProfile LoadProfile(int id) - { - string profileID = ProfileData.Profiles.Where(p => p.Id == id.ToString()).FirstOrDefault()?.Id.ToString(); - if (!string.IsNullOrEmpty(profileID)) - { - return LoadProfile(profileID); - } - - return null; - } internal static void AcquireNewProfile(string make, string model, string printerName) { @@ -223,11 +213,11 @@ namespace MatterHackers.MatterControl.SlicerConfiguration OemProfile printerProfile = LoadHttpOemProfile(make, model); SettingsLayer baseConfig = LoadMatterHackersBaseLayer(); - var layeredProfile = new LayeredProfile( - printerProfile, - baseConfig); - layeredProfile.DocumentPath = Path.Combine(profilesPath, guid + ".json"); - layeredProfile.UserLayer["MatterControl.PrinterID"] = guid.ToString(); + var layeredProfile = new LayeredProfile(printerProfile, baseConfig) + { + ID = guid, + DocumentPath = Path.Combine(profilesPath, guid + ".json") + }; layeredProfile.UserLayer["MatterControl.PrinterName"] = printerName; // Import named macros as defined in the following printers: (Airwolf Axiom, HD, HD-R, HD2x, HDL, HDx, Me3D Me2, Robo R1[+]) @@ -258,6 +248,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } + // Copy OemProfile presets into user layers + foreach(var layer in layeredProfile.OemProfile.MaterialLayers) + { + layeredProfile.MaterialLayers[layer.Key] = layer.Value; + } + + foreach (var layer in layeredProfile.OemProfile.QualityLayers) + { + layeredProfile.QualityLayers[layer.Key] = layer.Value; + } + layeredProfile.Save(); ProfileData.Profiles.Add(new PrinterInfo diff --git a/SlicerConfiguration/Settings/LayeredProfile.cs b/SlicerConfiguration/Settings/LayeredProfile.cs index b2236259b..4f6c40a71 100644 --- a/SlicerConfiguration/Settings/LayeredProfile.cs +++ b/SlicerConfiguration/Settings/LayeredProfile.cs @@ -33,6 +33,7 @@ using System.Linq; using System.Runtime.Serialization; using System; using System.IO; +using Newtonsoft.Json.Linq; namespace MatterHackers.MatterControl.SlicerConfiguration { @@ -43,8 +44,73 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public DateTime LastModified { get; set; } } + public static class ProfileMigrations + { + public static string MigrateDocument(string filePath, int fromVersion) + { + var jObject = JObject.Parse(File.ReadAllText(filePath)); + + if (fromVersion < 201605131) + { + var materialLayers = jObject["MaterialLayers"] as JObject; + foreach (JProperty layer in materialLayers.Properties().ToList()) + { + layer.Remove(); + + string layerID = Guid.NewGuid().ToString(); + + var body = layer.Value as JObject; + body["MatterControl.LayerID"] = layerID; + body["MatterControl.LayerName"] = layer.Name; + + materialLayers[layerID] = layer.Value; + } + + var qualityLayers = jObject["QualityLayers"] as JObject; + foreach (JProperty layer in qualityLayers.Properties().ToList()) + { + layer.Remove(); + + string layerID = Guid.NewGuid().ToString(); + + var body = layer.Value as JObject; + body["MatterControl.LayerID"] = layerID; + body["MatterControl.LayerName"] = layer.Name; + + qualityLayers[layerID] = layer.Value; + } + + + jObject["DocumentVersion"] = 201605131; + } + + if (fromVersion < 201605132) + { + string printerID = Guid.NewGuid().ToString(); + jObject.Remove("DocumentPath"); + jObject["ID"] = printerID; + jObject["DocumentVersion"] = 201605132; + + File.Delete(filePath); + filePath = Path.Combine(Path.GetDirectoryName(filePath), printerID + ".json"); + } + + File.WriteAllText( + filePath, + JsonConvert.SerializeObject(jObject, Formatting.Indented)); + + return filePath; + } + } + public class LayeredProfile { + public int DocumentVersion { get; set; } + + public string ID { get; set; } + + public static int LatestVersion { get; } = 201605132; + [JsonIgnore] internal SettingsLayer QualityLayer { get; private set; } @@ -126,7 +192,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } - public string GetMaterialPresetKey(int extruderIndex) { if (extruderIndex >= MaterialSettingsKeys.Count) @@ -165,13 +230,14 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public List MaterialSettingsKeys { get; set; } = new List(); + [JsonIgnore] public string DocumentPath { get; set; } internal void Save() { if (!string.IsNullOrEmpty(DocumentPath)) { - File.WriteAllText(DocumentPath, JsonConvert.SerializeObject(this)); + File.WriteAllText(DocumentPath, JsonConvert.SerializeObject(this, Formatting.Indented)); } } @@ -180,19 +246,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration /// public SettingsLayer UserLayer { get; } = new SettingsLayer(); - public IEnumerable AllMaterialKeys() - { - return MaterialLayers.Keys.Union(this.OemProfile.MaterialLayers.Keys); - } - - public IEnumerable AllQualityKeys() - { - return QualityLayers.Keys.Union(this.OemProfile.QualityLayers.Keys); - } - internal static LayeredProfile LoadFile(string printerProfilePath) { var layeredProfile = JsonConvert.DeserializeObject(File.ReadAllText(printerProfilePath)); + if (layeredProfile.DocumentVersion < LayeredProfile.LatestVersion) + { + printerProfilePath = ProfileMigrations.MigrateDocument(printerProfilePath, layeredProfile.DocumentVersion); + + // Reload the document with the new schema + layeredProfile = JsonConvert.DeserializeObject(File.ReadAllText(printerProfilePath)); + } + layeredProfile.DocumentPath = printerProfilePath; return layeredProfile; @@ -210,18 +274,22 @@ namespace MatterHackers.MatterControl.SlicerConfiguration /// public Dictionary QualityLayers { get; } = new Dictionary(); - /// ///Returns the settings value at the 'top' of the stack /// public string GetValue(string sliceSetting) { - return GetValue(sliceSetting, settingsLayers); + return GetValue(sliceSetting, defaultLayerCascade); } - public string GetValue(string sliceSetting, IEnumerable layers) + public string GetValue(string sliceSetting, IEnumerable layerCascade) { - foreach (SettingsLayer layer in layers) + if (layerCascade == null) + { + layerCascade = defaultLayerCascade; + } + + foreach (SettingsLayer layer in layerCascade) { string value; if (layer.TryGetValue(sliceSetting, out value)) @@ -235,7 +303,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public SettingsLayer BaseLayer { get; set; } - private IEnumerable settingsLayers + private IEnumerable defaultLayerCascade { get { diff --git a/SlicerConfiguration/Settings/SettingsProfile.cs b/SlicerConfiguration/Settings/SettingsProfile.cs index fea8ec713..bd70d3ecd 100644 --- a/SlicerConfiguration/Settings/SettingsProfile.cs +++ b/SlicerConfiguration/Settings/SettingsProfile.cs @@ -64,13 +64,25 @@ namespace MatterHackers.MatterControl.SlicerConfiguration layeredProfile = profile; } + public string ID => layeredProfile.ID; + public SettingsLayer BaseLayer => layeredProfile.BaseLayer; public SettingsLayer OemLayer => layeredProfile.OemProfile.OemLayer; public SettingsLayer UserLayer => layeredProfile.UserLayer; - public string ActiveMaterialKey => layeredProfile.ActiveMaterialKey; + public string ActiveMaterialKey + { + get + { + return layeredProfile.ActiveMaterialKey; + } + set + { + layeredProfile.ActiveMaterialKey = value; + } + } public string ActiveQualityKey { @@ -92,15 +104,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration // Commit } - public IEnumerable AllMaterialKeys() - { - return layeredProfile.AllMaterialKeys(); - } + public Dictionary MaterialLayers => layeredProfile.MaterialLayers; - public IEnumerable AllQualityKeys() - { - return layeredProfile.AllQualityKeys(); - } + public Dictionary QualityLayers => layeredProfile.QualityLayers; public class SettingsConverter { @@ -176,23 +182,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration return layeredProfile.GetMaterialLayer(key); } - internal SettingsLayer CreatePresetsLayer(NamedSettingsLayers layerType) - { - SettingsLayer newLayer = new SettingsLayer(); - if (layerType == NamedSettingsLayers.Quality) - { - newLayer.Name = "Quality" + layeredProfile.QualityLayers.Count; - layeredProfile.QualityLayers[newLayer.Name] = newLayer; - } - else - { - newLayer.Name = "Material" + layeredProfile.MaterialLayers.Count; - layeredProfile.MaterialLayers[newLayer.Name] = newLayer; - } - - return newLayer; - } - internal SettingsLayer QualityLayer(string key) { return layeredProfile.GetQualityLayer(key); @@ -563,9 +552,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration return layeredProfile.GetValue(sliceSetting); } - public string GetActiveValue(string sliceSetting, IEnumerable layers) + public string GetActiveValue(string sliceSetting, IEnumerable layerCascade) { - return layeredProfile.GetValue(sliceSetting, layers); + return layeredProfile.GetValue(sliceSetting, layerCascade); } public void SetActiveValue(string sliceSetting, string sliceValue) @@ -924,16 +913,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration layeredProfile.SetActiveValue("MatterControl.PrinterName", name); } - public string Id() - { - return layeredProfile.GetValue("MatterControl.PrinterID"); - } - - public void SetId(string id) - { - layeredProfile.SetActiveValue("MatterControl.PrinterID", id); - } - public string Model => layeredProfile.GetValue("MatterControl.Model"); HashSet knownSettings = null; @@ -1047,9 +1026,61 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } - public string Name { get; set; } - public string Source { get; set; } - public string ETag { get; set; } + public string ID + { + get + { + // TODO: Short term hack to silently upgrade existing profiles with missing ID + string layerKey = ValueOrDefault("MatterControl.LayerID"); + if (string.IsNullOrEmpty(layerKey)) + { + layerKey = Guid.NewGuid().ToString(); + ID = layerKey; + } + + return layerKey; + } + set + { + this["MatterControl.LayerID"] = value; + } + } + + public string Name + { + get + { + return ValueOrDefault("MatterControl.LayerName"); + } + set + { + this["MatterControl.LayerName"] = value; + } + } + + public string Source + { + get + { + return ValueOrDefault("MatterControl.LayerSource"); + } + set + { + this["MatterControl.LayerSource"] = value; + } + } + + public string ETag + { + get + { + return ValueOrDefault("MatterControl.LayerETag"); + } + set + { + this["MatterControl.LayerETag"] = value; + } + } public string ValueOrDefault(string key, string defaultValue = "") { @@ -1104,6 +1135,18 @@ namespace MatterHackers.MatterControl.SlicerConfiguration return layer; } + + public SettingsLayer Clone() + { + string id = Guid.NewGuid().ToString(); + return new SettingsLayer(this as Dictionary) + { + ID = id, + Name = this.Name, + ETag = this.ETag, + Source = this.Source + }; + } } public class ProfileData diff --git a/SlicerConfiguration/SettingsControlSelectors.cs b/SlicerConfiguration/SettingsControlSelectors.cs index 0f8863def..8d8178270 100644 --- a/SlicerConfiguration/SettingsControlSelectors.cs +++ b/SlicerConfiguration/SettingsControlSelectors.cs @@ -108,7 +108,13 @@ namespace MatterHackers.MatterControl.SlicerConfiguration return; } - ApplicationController.Instance.EditMaterialPresetsWindow = new SlicePresetsWindow(ActiveSliceSettings.Instance.MaterialLayer(presetsKey), NamedSettingsLayers.Material, presetsKey); + var presetsContext = new PresetsContext(ActiveSliceSettings.Instance.MaterialLayers, presetsKey) + { + LayerType = NamedSettingsLayers.Material, + SetAsActive = (materialKey) => ActiveSliceSettings.Instance.ActiveMaterialKey = materialKey + }; + + ApplicationController.Instance.EditMaterialPresetsWindow = new SlicePresetsWindow(presetsContext); ApplicationController.Instance.EditMaterialPresetsWindow.Closed += (s, e2) => { ApplicationController.Instance.EditMaterialPresetsWindow = null; @@ -132,7 +138,13 @@ namespace MatterHackers.MatterControl.SlicerConfiguration return; } - ApplicationController.Instance.EditQualityPresetsWindow = new SlicePresetsWindow(ActiveSliceSettings.Instance.QualityLayer(presetsKey), NamedSettingsLayers.Quality, presetsKey); + var presetsContext = new PresetsContext(ActiveSliceSettings.Instance.QualityLayers, presetsKey) + { + LayerType = NamedSettingsLayers.Quality, + SetAsActive = (qualityKey) => ActiveSliceSettings.Instance.ActiveQualityKey = qualityKey + }; + + ApplicationController.Instance.EditQualityPresetsWindow = new SlicePresetsWindow(presetsContext); ApplicationController.Instance.EditQualityPresetsWindow.Closed += (s, e2) => { ApplicationController.Instance.EditQualityPresetsWindow = null; @@ -193,23 +205,33 @@ namespace MatterHackers.MatterControl.SlicerConfiguration MenuItem defaultMenuItem = dropDownList.AddItem("- default -", ""); defaultMenuItem.Selected += MenuItem_Selected; - var listSource = (layerType == NamedSettingsLayers.Material) ? ActiveSliceSettings.Instance.AllMaterialKeys() : ActiveSliceSettings.Instance.AllQualityKeys(); - foreach (var presetName in listSource) + var listSource = (layerType == NamedSettingsLayers.Material) ? ActiveSliceSettings.Instance.MaterialLayers : ActiveSliceSettings.Instance.QualityLayers; + foreach (var layer in listSource) { - MenuItem menuItem = dropDownList.AddItem(presetName, presetName); + if (string.IsNullOrEmpty(layer.Value.Name)) + { + layer.Value.Name = layer.Key; + } + + MenuItem menuItem = dropDownList.AddItem(layer.Value.Name, layer.Value.ID); menuItem.Selected += MenuItem_Selected; } MenuItem addNewPreset = dropDownList.AddItem(StaticData.Instance.LoadIcon("icon_plus.png", 32, 32), "Add New Setting...", "new"); addNewPreset.Selected += (s, e) => { - var newLayer = ActiveSliceSettings.Instance.CreatePresetsLayer(layerType); + var newLayer = new SettingsLayer(); if (layerType == NamedSettingsLayers.Quality) { - ActiveSliceSettings.Instance.ActiveQualityKey = newLayer.Name; + newLayer.Name = "Quality" + ActiveSliceSettings.Instance.QualityLayers.Count; + ActiveSliceSettings.Instance.QualityLayers[newLayer.Name] = newLayer; + ActiveSliceSettings.Instance.ActiveQualityKey = newLayer.ID; } - else if (layerType == NamedSettingsLayers.Material) + else { + newLayer.Name = "Material" + ActiveSliceSettings.Instance.MaterialLayers.Count; + ActiveSliceSettings.Instance.MaterialLayers[newLayer.Name] = newLayer; + ActiveSliceSettings.Instance.ActiveMaterialKey = newLayer.ID; ActiveSliceSettings.Instance.SetMaterialPreset(this.extruderIndex, newLayer.Name); } diff --git a/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs b/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs index 838481135..97cd0cb34 100644 --- a/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs +++ b/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs @@ -36,39 +36,55 @@ using MatterHackers.MatterControl.DataStorage.ClassicDB; using MatterHackers.VectorMath; using System; using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; namespace MatterHackers.MatterControl.SlicerConfiguration { + public class PresetsContext + { + public Dictionary PresetsDictionary { get; } + public SettingsLayer PersistenceLayer { get; } + public Action SetAsActive { get; set; } + public NamedSettingsLayers LayerType { get; set; } + + private string presetsKey; + + public PresetsContext(Dictionary parentDictionary, string presetsKey) + { + this.presetsKey = presetsKey; + this.PersistenceLayer = parentDictionary[presetsKey]; + this.PresetsDictionary = parentDictionary; + } + } + public class SlicePresetsWindow : SystemWindow { - private string presetsKey; - private SettingsLayer persistenceLayer; - private NamedSettingsLayers layerType; - - private TextImageButtonFactory buttonFactory; - private LinkButtonFactory linkButtonFactory; + private PresetsContext presetsContext; private MHTextEditWidget presetNameInput; + private string initialPresetName = null; private string configFileExtension = "slice"; - public SlicePresetsWindow(SettingsLayer persistenceLayer, NamedSettingsLayers layerType, string presetsKey) + private static Regex numberMatch = new Regex("\\s*\\(\\d+\\)", RegexOptions.Compiled); + + + public SlicePresetsWindow(PresetsContext presetsContext) : base(641, 481) { + this.presetsContext = presetsContext; this.AlwaysOnTopOfMain = true; this.Title = LocalizedString.Get("Slice Presets Editor"); - this.persistenceLayer = persistenceLayer; - this.layerType = layerType; - this.presetsKey = presetsKey; this.MinimumSize = new Vector2(640, 480); this.AnchorAll(); - linkButtonFactory = new LinkButtonFactory() + var linkButtonFactory = new LinkButtonFactory() { fontSize = 8, textColor = ActiveTheme.Instance.SecondaryAccentColor }; - buttonFactory = new TextImageButtonFactory() + var buttonFactory = new TextImageButtonFactory() { normalTextColor = ActiveTheme.Instance.PrimaryTextColor, hoverTextColor = ActiveTheme.Instance.PrimaryTextColor, @@ -85,39 +101,37 @@ namespace MatterHackers.MatterControl.SlicerConfiguration mainContainer.AddChild(GetTopRow()); mainContainer.AddChild(GetMiddleRow()); - mainContainer.AddChild(GetBottomRow()); + mainContainer.AddChild(GetBottomRow(buttonFactory)); this.AddChild(mainContainer); BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor; - } private FlowLayoutWidget GetTopRow() { - FlowLayoutWidget metaContainer = new FlowLayoutWidget(FlowDirection.TopToBottom) + var metaContainer = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.ParentLeftRight, Padding = new BorderDouble(0, 3) }; - FlowLayoutWidget firstRow = new FlowLayoutWidget(hAnchor: HAnchor.ParentLeftRight); - - TextWidget labelText = new TextWidget("Preset Name:".Localize(), pointSize: 14) + var labelText = new TextWidget("Preset Name:".Localize(), pointSize: 14) { TextColor = ActiveTheme.Instance.PrimaryTextColor, VAnchor = VAnchor.ParentCenter, Margin = new BorderDouble(right: 4) }; - presetNameInput = new MHTextEditWidget(this.presetsKey); + initialPresetName = presetsContext.PersistenceLayer.Name; + presetNameInput = new MHTextEditWidget(initialPresetName); presetNameInput.HAnchor = HAnchor.ParentLeftRight; + var firstRow = new FlowLayoutWidget(hAnchor: HAnchor.ParentLeftRight); firstRow.AddChild(labelText); firstRow.AddChild(presetNameInput); - FlowLayoutWidget secondRow = new FlowLayoutWidget(hAnchor: HAnchor.ParentLeftRight); - + var secondRow = new FlowLayoutWidget(hAnchor: HAnchor.ParentLeftRight); secondRow.AddChild(new GuiWidget(labelText.Width + 4, 1)); metaContainer.AddChild(firstRow); @@ -129,36 +143,58 @@ namespace MatterHackers.MatterControl.SlicerConfiguration private GuiWidget GetMiddleRow() { var settings = ActiveSliceSettings.Instance; - var layerCascade = new List { settings.BaseLayer, settings.OemLayer, persistenceLayer }; + var layerCascade = new List { presetsContext.PersistenceLayer, settings.OemLayer, settings.BaseLayer}; - var settingsWidget = new SliceSettingsWidget(layerCascade, layerType); + var settingsWidget = new SliceSettingsWidget(layerCascade, presetsContext.LayerType); settingsWidget.settingsControlBar.Visible = false; return settingsWidget; } - private FlowLayoutWidget GetBottomRow() + private string GetNonCollidingName(string profileName, IEnumerable existingNames) { - FlowLayoutWidget container = new FlowLayoutWidget() + if (!existingNames.Contains(profileName)) + { + return profileName; + } + else + { + + int currentIndex = 1; + string possiblePrinterName; + + do + { + possiblePrinterName = String.Format("{0} ({1})", profileName, currentIndex++); + } while (existingNames.Contains(possiblePrinterName)); + + return possiblePrinterName; + } + } + + private FlowLayoutWidget GetBottomRow(TextImageButtonFactory buttonFactory) + { + var container = new FlowLayoutWidget() { HAnchor = HAnchor.ParentLeftRight, Margin = new BorderDouble(top: 3) }; - Button saveButton = buttonFactory.Generate("Save".Localize()); - saveButton.Click += (s, e) => - { - throw new NotImplementedException(); - }; - Button duplicateButton = buttonFactory.Generate("Duplicate".Localize()); duplicateButton.Click += (s, e) => { UiThread.RunOnIdle(() => { - // duplicatePresets_Click - // TODO: copy existing dictionary to new named instance - throw new NotImplementedException(); + string sanitizedName = numberMatch.Replace(presetNameInput.Text, "").Trim(); + string newProfileName = GetNonCollidingName(sanitizedName, presetsContext.PresetsDictionary.Values.Select(preset => preset.Name)); + + this.Close(); + + var clonedLayer = presetsContext.PersistenceLayer.Clone(); + clonedLayer.Name = newProfileName; + presetsContext.PresetsDictionary[clonedLayer.ID] = clonedLayer; + + presetsContext.SetAsActive(clonedLayer.ID); }); }; @@ -174,15 +210,25 @@ namespace MatterHackers.MatterControl.SlicerConfiguration Button closeButton = buttonFactory.Generate("Close".Localize()); closeButton.Click += (sender, e) => { - UiThread.RunOnIdle(this.Close); + UiThread.RunOnIdle(() => + { + if (initialPresetName != presetNameInput.Text) + { + presetsContext.PersistenceLayer.Name = presetNameInput.Text; + + // TODO: If we get to the point where we refresh rather than reload, we need + // to rebuild the target droplist to display the new name + ApplicationController.Instance.ReloadAdvancedControlsPanel(); + } + this.Close(); + }); }; - container.AddChild(saveButton); + container.AddChild(duplicateButton); //Only show duplicate/import/export buttons if setting has been saved. if (false) { - container.AddChild(duplicateButton); container.AddChild(importButton); container.AddChild(exportButton); } diff --git a/SlicerConfiguration/SliceSettingsWidget.cs b/SlicerConfiguration/SliceSettingsWidget.cs index 9c5fe909c..9509d2385 100644 --- a/SlicerConfiguration/SliceSettingsWidget.cs +++ b/SlicerConfiguration/SliceSettingsWidget.cs @@ -91,18 +91,18 @@ namespace MatterHackers.MatterControl.SlicerConfiguration private TextImageButtonFactory textImageButtonFactory; - private List layerFilters = null; + private List layerCascade = null; private SettingsLayer persistenceLayer = null; private NamedSettingsLayers viewFilter; - public SliceSettingsWidget(List layerFilters = null, NamedSettingsLayers viewFilter = NamedSettingsLayers.All) + public SliceSettingsWidget(List layerCascade = null, NamedSettingsLayers viewFilter = NamedSettingsLayers.All) { - this.layerFilters = layerFilters; + this.layerCascade = layerCascade; this.viewFilter = viewFilter; // The last layer of the layerFilters is the target persistence layer - persistenceLayer = layerFilters?.Last() ?? ActiveSliceSettings.Instance.UserLayer; + persistenceLayer = layerCascade?.First() ?? ActiveSliceSettings.Instance.UserLayer; textImageButtonFactory = new TextImageButtonFactory(); textImageButtonFactory.normalFillColor = RGBA_Bytes.Transparent; @@ -464,7 +464,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration return leftSideGroupTabs; } - private static bool CheckIfShouldBeShown(OrganizerSettingsData settingInfo) + private bool CheckIfShouldBeShown(OrganizerSettingsData settingInfo) { bool settingShouldBeShown = true; if (settingInfo.ShowIfSet != null @@ -477,7 +477,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration showValue = "1"; checkName = checkName.Substring(1); } - string sliceSettingValue = ActiveSliceSettings.Instance.ActiveValue(checkName); + string sliceSettingValue = GetActiveValue(checkName, layerCascade); if (sliceSettingValue == showValue) { settingShouldBeShown = false; @@ -601,9 +601,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration HAnchor = Agg.UI.HAnchor.ParentLeftRight; } - public void RefreshValue() + public void RefreshValue(IEnumerable layerFilters) { - string latestValue = ActiveSliceSettings.Instance.ActiveValue(this.SettingsKey); + string latestValue = GetActiveValue(this.SettingsKey, layerFilters); //if(latestValue != SettingsValue) { ValueChanged?.Invoke(latestValue); @@ -619,12 +619,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration private static readonly RGBA_Bytes userSettingBackgroundColor = new RGBA_Bytes(68, 95, 220, 108); private static readonly RGBA_Bytes qualitySettingBackgroundColor = new RGBA_Bytes(255, 255, 0, 108); + private static string GetActiveValue(string slicerConfigName, IEnumerable layerCascade) + { + return ActiveSliceSettings.Instance.GetActiveValue(slicerConfigName, layerCascade); + } + private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double rightContentWidth, int extruderIndex) { GuiWidget container = new GuiWidget(); this.HAnchor = HAnchor.ParentLeftRight; - string sliceSettingValue = ActiveSliceSettings.Instance.ActiveValue(settingData.SlicerConfigName); + string sliceSettingValue = GetActiveValue(settingData.SlicerConfigName, layerCascade); GuiWidget nameArea = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren | VAnchor.ParentCenter); var dataArea = new FlowLayoutWidget(); @@ -765,10 +770,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration if (ChangesMultipleOtherSettings) { bool allTheSame = true; - string setting = ActiveSliceSettings.Instance.ActiveValue(settingData.SetSettingsOnChange[0]); + string setting = GetActiveValue(settingData.SetSettingsOnChange[0], layerCascade); for (int i = 1; i < settingData.SetSettingsOnChange.Count; i++) { - string nextSetting = ActiveSliceSettings.Instance.ActiveValue(settingData.SetSettingsOnChange[i]); + string nextSetting = GetActiveValue(settingData.SetSettingsOnChange[i], layerCascade); if (setting != nextSetting) { allTheSame = false; @@ -1373,7 +1378,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration ActiveSliceSettings.Instance.ClearValue(settingData.SlicerConfigName, persistenceLayer); } - settingsRow.RefreshValue(); + settingsRow.RefreshValue(layerCascade); }; restoreArea.AddChild(restoreButton); @@ -1400,7 +1405,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration restoreButton.Visible = true; } - else if (layerFilters == null) + else if (layerCascade == null) { if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, NamedSettingsLayers.Material)) { @@ -1496,7 +1501,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration private GuiWidget CreateQuickMenu(OrganizerSettingsData settingData, GuiWidget content, InternalTextEditWidget internalTextWidget) { - string sliceSettingValue = ActiveSliceSettings.Instance.ActiveValue(settingData.SlicerConfigName); + string sliceSettingValue = GetActiveValue(settingData.SlicerConfigName, layerCascade); FlowLayoutWidget totalContent = new FlowLayoutWidget(); StyledDropDownList selectableOptions = new StyledDropDownList("Custom", maxHeight: 200); @@ -1534,7 +1539,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration foreach (QuickMenuNameValue nameValue in settingData.QuickMenuSettings) { string localName = nameValue.MenuName; - string newSliceSettingValue = ActiveSliceSettings.Instance.ActiveValue(settingData.SlicerConfigName); + string newSliceSettingValue = GetActiveValue(settingData.SlicerConfigName, layerCascade); if (newSliceSettingValue == nameValue.Value) { selectableOptions.SelectedLabel = localName; @@ -1554,7 +1559,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration private void SaveCommaSeparatedIndexSetting(int extruderIndexLocal, string slicerConfigName, string newSingleValue) { - string[] settings = ActiveSliceSettings.Instance.ActiveValue(slicerConfigName).Split(','); + string[] settings = GetActiveValue(slicerConfigName, layerCascade).Split(','); if (settings.Length > extruderIndexLocal) { settings[extruderIndexLocal] = newSingleValue;