diff --git a/MatterControl.csproj b/MatterControl.csproj index d7fd37560..d81db45fe 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -248,6 +248,7 @@ + diff --git a/SetupWizard/ImportSettingsPage.cs b/SetupWizard/ImportSettingsPage.cs new file mode 100644 index 000000000..4f0e61961 --- /dev/null +++ b/SetupWizard/ImportSettingsPage.cs @@ -0,0 +1,156 @@ +/* +Copyright (c) 2016, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System; + +using MatterHackers.Agg.UI; +using MatterHackers.MatterControl; +using MatterHackers.MatterControl.CustomWidgets; +using MatterHackers.MatterControl.SlicerConfiguration; +using MatterHackers.Localizations; +using System.IO; +using MatterHackers.Agg; + +namespace MatterHackers.MatterControl +{ + public class ImportSettingsPage : WizardPage + { + private string importMode; + + public ImportSettingsPage() : + base("Cancel") + { + var container = new FlowLayoutWidget(FlowDirection.TopToBottom); + contentRow.AddChild(container); + + var newPrinterButton = new RadioButton("Import as new printer profile".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor); + newPrinterButton.CheckedStateChanged += (s, e) => importMode = "new"; + newPrinterButton.Checked = true; + container.AddChild(newPrinterButton); + this.importMode = "new"; + + var mergeButton = new RadioButton("Merge into current printer profile".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor); + mergeButton.CheckedStateChanged += (s, e) => importMode = "merge"; + container.AddChild(mergeButton); + + var replaceButton = new RadioButton("Replace current printer profile".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor); + replaceButton.CheckedStateChanged += (s, e) => importMode = "replace"; + container.AddChild(replaceButton); + + var importButton = textImageButtonFactory.Generate("Import Settings".Localize()); + importButton.Click += (s, e) => UiThread.RunOnIdle(() => + { + FileDialog.OpenFileDialog( + new OpenFileDialogParams("settings files|*.ini;*.printer,"), + (dialogParams) => ImportSettingsFile(dialogParams.FileName)); + }); + + importButton.Visible = true; + cancelButton.Visible = true; + + //Add buttons to buttonContainer + footerRow.AddChild(importButton); + footerRow.AddChild(new HorizontalSpacer()); + footerRow.AddChild(cancelButton); + } + + private void ImportSettingsFile(string settingsFilePath) + { + WizardWindow.Close(); + + switch (importMode) + { + case "new": + ActiveSliceSettings.ImportFromExisting(settingsFilePath); + break; + + case "merge": + case "replace": + ReplaceOrMergeSettings(settingsFilePath); + break; + } + } + + private void ReplaceOrMergeSettings(string settingsFilePath) + { + if (!string.IsNullOrEmpty(settingsFilePath) && File.Exists(settingsFilePath)) + { + string importType = Path.GetExtension(settingsFilePath).ToLower(); + switch (importType) + { + case ".printer": + throw new NotImplementedException("need to import from 'MatterControl.printer' files"); + break; + + case ".ini": + var settingsToImport = SettingsLayer.LoadFromIni(settingsFilePath); + string layerHeight; + + bool isSlic3r = settingsToImport.TryGetValue("layer_height", out layerHeight); + if (isSlic3r) + { + var activeSettings = ActiveSliceSettings.Instance; + + if (importMode == "replace") + { + activeSettings.ClearUserOverrides(); + } + + foreach (var item in settingsToImport) + { + // Compare the value to import to the layer cascade value and only set if different + string currentValue = activeSettings.GetActiveValue(item.Key, null).Trim(); + if (currentValue != item.Value) + { + activeSettings.UserLayer[item.Key] = item.Value; + } + } + + activeSettings.SaveChanges(); + + UiThread.RunOnIdle(ApplicationController.Instance.ReloadAdvancedControlsPanel); + } + else + { + // looks like a cura file + throw new NotImplementedException("need to import from 'cure.ini' files"); + } + break; + + default: + // Did not figure out what this file is, let the user know we don't understand it + StyledMessageBox.ShowMessageBox(null, "Oops! Unable to recognize settings file '{0}'.".Localize().FormatWith(Path.GetFileName(settingsFilePath)), "Unable to Import".Localize()); + break; + } + + } + Invalidate(); + } + } +} diff --git a/SlicerConfiguration/Settings/ActiveSliceSettings.cs b/SlicerConfiguration/Settings/ActiveSliceSettings.cs index f34c44fdb..d3c4662a3 100644 --- a/SlicerConfiguration/Settings/ActiveSliceSettings.cs +++ b/SlicerConfiguration/Settings/ActiveSliceSettings.cs @@ -248,6 +248,54 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } + internal static void ImportFromExisting(string settingsFilePath) + { + if (string.IsNullOrEmpty(settingsFilePath) || !File.Exists(settingsFilePath)) + { + return; + } + + var printerIdentifier = new PrinterInfo + { + Name = Path.GetFileNameWithoutExtension(settingsFilePath), + Id = Guid.NewGuid().ToString() + }; + + string importType = Path.GetExtension(settingsFilePath).ToLower(); + switch (importType) + { + case ".printer": + var profile = LoadProfileFromDisk(settingsFilePath); + profile.ID = Guid.NewGuid().ToString(); + break; + + case ".ini": + var settingsToImport = SettingsLayer.LoadFromIni(settingsFilePath); + + var oemProfile = new OemProfile(settingsToImport); + SettingsLayer baseConfig = LoadMatterHackersBaseLayer(); + + var layeredProfile = new LayeredProfile(oemProfile, baseConfig) + { + ID = printerIdentifier.Id, + DocumentPath = Path.Combine(profilesPath, printerIdentifier.Id + ".json") + }; + + // TODO: Resolve name conflicts + layeredProfile.UserLayer["MatterControl.PrinterName"] = printerIdentifier.Name; + layeredProfile.Save(); + + break; + } + + ProfileData.Profiles.Add(printerIdentifier); + + UserSettings.Instance.set("ActiveProfileID", printerIdentifier.Id); + + Instance = LoadProfile(printerIdentifier.Id); + } + + internal static void AcquireNewProfile(string make, string model, string printerName) { string guid = Guid.NewGuid().ToString(); diff --git a/SlicerConfiguration/Settings/SettingsProfile.cs b/SlicerConfiguration/Settings/SettingsProfile.cs index 5714e4951..c95c37ffe 100644 --- a/SlicerConfiguration/Settings/SettingsProfile.cs +++ b/SlicerConfiguration/Settings/SettingsProfile.cs @@ -65,7 +65,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration layeredProfile = profile; } - public string ID => layeredProfile.ID; + public string ID + { + get + { + return layeredProfile.ID; + } + set + { + layeredProfile.ID = value; + } + } public SettingsLayer BaseLayer => layeredProfile.BaseLayer; @@ -146,6 +156,39 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } + public void ClearUserOverrides() + { + var userOverrides = this.UserLayer.Keys.ToArray(); + + // Leave user layer items that have no Organizer definition and thus cannot be changed by the user + var keysToRetain = new HashSet(userOverrides.Except(this.KnownSettings)); + + foreach (var item in SliceSettingsOrganizer.Instance.SettingsData.Where(settingsItem => !settingsItem.ShowAsOverride)) + { + switch (item.SlicerConfigName) + { + case "MatterControl.BaudRate": + case "MatterControl.AutoConnect": + // These items are marked as not being overrides but should be cleared on 'reset to defaults' + break; + default: + // All other non-overrides should be retained + keysToRetain.Add(item.SlicerConfigName); + break; + } + } + + var keysToRemove = (from keyValue in this.UserLayer + where !keysToRetain.Contains(keyValue.Key) + select keyValue.Key).ToList(); + + foreach (string key in keysToRemove) + { + this.UserLayer.Remove(key); + } + } + + internal void SaveChanges() { layeredProfile.Save(); diff --git a/SlicerConfiguration/SliceSettingsDetailControl.cs b/SlicerConfiguration/SliceSettingsDetailControl.cs index c86e2b06d..91e41f927 100644 --- a/SlicerConfiguration/SliceSettingsDetailControl.cs +++ b/SlicerConfiguration/SliceSettingsDetailControl.cs @@ -99,73 +99,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration private bool ImportSettingsMenu_Click() { - UiThread.RunOnIdle(() => - { - OpenFileDialogParams openParams = new OpenFileDialogParams("settings files|*.ini;*.printer,"); - FileDialog.OpenFileDialog(openParams, settingsImportFileSelected); - }); - + UiThread.RunOnIdle(() => WizardWindow.Show("ImportSettingsPage", "Import Settings Page")); return true; } - private void settingsImportFileSelected(OpenFileDialogParams openParams) - { - if (!string.IsNullOrEmpty(openParams.FileName)) - { - // figure out what type it is - if (Path.GetExtension(openParams.FileName).ToLower() == ".printer") - { - throw new NotImplementedException("need to import from 'MatterControl.printer' files"); - // done loading return - return; - } - else - { - var settingsToImport = SettingsLayer.LoadFromIni(openParams.FileName); - string layerHeight; - - bool isSlic3r = settingsToImport.TryGetValue("layer_height", out layerHeight); - if (isSlic3r) - { - // looks like a slic3r file - ClearUserOverrides(); - - var activeSettings = ActiveSliceSettings.Instance; - - foreach (var item in settingsToImport) - { - // Compare the value to import to the layer cascade value and only set if different - string currentValue = activeSettings.GetActiveValue(item.Key, null).Trim(); - if (currentValue != item.Value) - { - activeSettings.UserLayer[item.Key] = item.Value; - } - } - - activeSettings.SaveChanges(); - - UiThread.RunOnIdle(ApplicationController.Instance.ReloadAdvancedControlsPanel); - - // done loading return - return; - } - else - { - // looks like a cura file - throw new NotImplementedException("need to import from 'cure.ini' files"); - // done loading return - return; - } - } - - // Did not figure out what this file is, let the user know we don't understand it - StyledMessageBox.ShowMessageBox(null, "Oops! Unable to recognize settings file '{0}'.".Localize().FormatWith(Path.GetFileName(openParams.FileName)), "Unable to Import".Localize()); - } - - Invalidate(); - } - - private void MenuDropList_SelectionChanged(object sender, EventArgs e) { string menuSelection = ((DropDownMenu)sender).SelectedValue; @@ -193,7 +130,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { if (revertSettings) { - ClearUserOverrides(); + ActiveSliceSettings.Instance.ClearUserOverrides(); ActiveSliceSettings.Instance.SaveChanges(); ApplicationController.Instance.ReloadAdvancedControlsPanel(); } @@ -203,37 +140,5 @@ namespace MatterHackers.MatterControl.SlicerConfiguration StyledMessageBox.MessageType.YES_NO); } - private static void ClearUserOverrides() - { - var activeSettings = ActiveSliceSettings.Instance; - var userOverrides = activeSettings.UserLayer.Keys.ToArray(); - - // Leave user layer items that have no Organizer definition and thus cannot be changed by the user - var keysToRetain = new HashSet(userOverrides.Except(activeSettings.KnownSettings)); - - foreach (var item in SliceSettingsOrganizer.Instance.SettingsData.Where(settingsItem => !settingsItem.ShowAsOverride)) - { - switch (item.SlicerConfigName) - { - case "MatterControl.BaudRate": - case "MatterControl.AutoConnect": - // These items are marked as not being overrides but should be cleared on 'reset to defaults' - break; - default: - // All other non-overrides should be retained - keysToRetain.Add(item.SlicerConfigName); - break; - } - } - - var keysToRemove = (from keyValue in activeSettings.UserLayer - where !keysToRetain.Contains(keyValue.Key) - select keyValue.Key).ToList(); - - foreach (string key in keysToRemove) - { - activeSettings.UserLayer.Remove(key); - } - } } } \ No newline at end of file diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 9b20efc56..dc4ba2923 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 9b20efc564ea56a9da0bfc92b8170a8fd82a7592 +Subproject commit dc4ba2923f3e731a6828df0ba3e20fbc93157227