From aae2ffdf764026a0b4ca1f633ab7b8322b514b36 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 7 Dec 2018 18:41:32 -0800 Subject: [PATCH] Revise tab ordering and persistence logic - Issue MatterHackers/MCCentral#4555 --- .../ApplicationView/ApplicationController.cs | 205 ++++++++++++++---- MatterControlLib/ApplicationView/BedConfig.cs | 8 +- .../ApplicationView/LibraryItemConverter.cs | 77 +++++++ .../ApplicationView/PartWorkspace.cs | 34 ++- .../ApplicationView/PrinterConfig.cs | 7 +- .../Library/Widgets/LibraryWidget.cs | 3 +- .../PartPreviewWindow/MainViewWidget.cs | 37 ++-- .../PartPreviewWindow/SelectedObjectPanel.cs | 8 + MatterControlLib/RootSystemWindow.cs | 34 ++- .../Settings/ProfileManager.cs | 31 +-- .../MatterControl/MatterControlUtilities.cs | 2 +- 11 files changed, 347 insertions(+), 99 deletions(-) create mode 100644 MatterControlLib/ApplicationView/LibraryItemConverter.cs diff --git a/MatterControlLib/ApplicationView/ApplicationController.cs b/MatterControlLib/ApplicationView/ApplicationController.cs index 816de0967..c1e772dd8 100644 --- a/MatterControlLib/ApplicationView/ApplicationController.cs +++ b/MatterControlLib/ApplicationView/ApplicationController.cs @@ -29,9 +29,11 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading.Tasks; using MatterHackers.Agg; using MatterHackers.Agg.UI; @@ -40,10 +42,7 @@ using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.PrinterCommunication; using MatterHackers.MatterControl.PrintQueue; using MatterHackers.MatterControl.SlicerConfiguration; -using MatterHackers.MatterControl.DesignTools.Operations; using Newtonsoft.Json; -using System.Collections.ObjectModel; -using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("MatterControl.Tests")] [assembly: InternalsVisibleTo("MatterControl.AutomationTests")] @@ -73,17 +72,13 @@ namespace MatterHackers.MatterControl using MatterHackers.MatterControl.Library; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.PartPreviewWindow.View3D; - using MatterHackers.MatterControl.PluginSystem; using MatterHackers.MatterControl.PrinterControls.PrinterConnections; - using MatterHackers.MatterControl.SetupWizard; using MatterHackers.PolygonMesh; using MatterHackers.PolygonMesh.Processors; - using MatterHackers.RenderOpenGl; - using MatterHackers.SerialPortCommunication; using MatterHackers.VectorMath; using MatterHackers.VectorMath.TrackBall; using Newtonsoft.Json.Converters; - using Newtonsoft.Json.Serialization; + using Newtonsoft.Json.Linq; using SettingsManagement; [JsonConverter(typeof(StringEnumConverter))] @@ -109,16 +104,16 @@ namespace MatterHackers.MatterControl Titillium, }; - public class OpenPrintersChangedEventArgs : EventArgs + public class WorkspacesChangedEventArgs : EventArgs { - public OpenPrintersChangedEventArgs(PrinterConfig printer, OperationType operation) + public WorkspacesChangedEventArgs(PartWorkspace workspace, OperationType operation) { - this.Printer = printer; this.Operation = operation; + this.Workspace = workspace; } - public PrinterConfig Printer { get; } public OperationType Operation { get; } + public PartWorkspace Workspace { get; } public enum OperationType { Add, Remove } } @@ -269,10 +264,10 @@ namespace MatterHackers.MatterControl public RunningTasksConfig Tasks { get; set; } = new RunningTasksConfig(); - public IReadOnlyList ActivePrinters => _activePrinters; + public IEnumerable ActivePrinters => this.Workspaces.Where(w => w.Printer != null).Select(w => w.Printer); - // A list of printers which are open (i.e. displaying a tab) on this instance of MatterControl - private List _activePrinters = new List(); + //// A list of printers which are open (i.e. displaying a tab) on this instance of MatterControl + //private List _activePrinters = new List(); private Dictionary> objectEditorsByType; @@ -395,7 +390,7 @@ namespace MatterHackers.MatterControl public RootedObjectEventHandler DoneReloadingAll = new RootedObjectEventHandler(); public RootedObjectEventHandler ActiveProfileModified = new RootedObjectEventHandler(); - public event EventHandler OpenPrintersChanged; + public event EventHandler WorkspacesChanged; public static Action WebRequestFailed; public static Action WebRequestSucceeded; @@ -412,9 +407,9 @@ namespace MatterHackers.MatterControl public static Func>> GetProfileHistory; - public void OnOpenPrintersChanged(OpenPrintersChangedEventArgs e) + public void OnWorkspacesChanged(WorkspacesChangedEventArgs e) { - this.OpenPrintersChanged?.Invoke(this, e); + this.WorkspacesChanged?.Invoke(this, e); } public string GetFavIconUrl(string oemName) @@ -428,11 +423,15 @@ namespace MatterHackers.MatterControl // Actually clear printer ProfileManager.Instance.ClosePrinter(printer.Settings.ID); - _activePrinters.Remove(printer); - if (allowChangedEvent) { - this.OnOpenPrintersChanged(new OpenPrintersChangedEventArgs(printer, OpenPrintersChangedEventArgs.OperationType.Remove)); + if (ApplicationController.Instance.Workspaces.FirstOrDefault(w => w.Printer.Settings.ID == printer.Settings.ID) is PartWorkspace workspace) + { + this.OnWorkspacesChanged( + new WorkspacesChangedEventArgs( + workspace, + WorkspacesChangedEventArgs.OperationType.Remove)); + } } printer.Dispose(); @@ -935,7 +934,7 @@ namespace MatterHackers.MatterControl { UiThread.RunOnIdle(() => { - if (printer != null || this.ActivePrinters.Count == 1) + if (printer != null || this.ActivePrinters.Count() == 1) { // If unspecified but count is one, select the one active printer if (printer == null) @@ -1032,7 +1031,7 @@ namespace MatterHackers.MatterControl ProfileManager.UserChanged += (s, e) => { - _activePrinters = new List(); + //_activePrinters = new List(); }; this.RebuildSceneOperations(this.Theme); @@ -1811,39 +1810,48 @@ namespace MatterHackers.MatterControl public async Task OpenPrinter(string printerID, bool loadPlateFromHistory = true) { - if (!_activePrinters.Any(p => p.Settings.ID == printerID)) + var printer = this.ActivePrinters.FirstOrDefault(p => p.Settings.ID == printerID); + if (printer == null) { - ProfileManager.Instance.OpenPrinter(printerID); - - var printer = new PrinterConfig(await ProfileManager.LoadSettingsAsync(printerID)); - - _activePrinters.Add(printer); + if (!string.IsNullOrEmpty(printerID) + && ProfileManager.Instance[printerID] != null) + { + printer = new PrinterConfig(await ProfileManager.LoadSettingsAsync(printerID)); + } if (loadPlateFromHistory) { await printer.Bed.LoadPlateFromHistory(); } - - this.OnOpenPrintersChanged(new OpenPrintersChangedEventArgs(printer, OpenPrintersChangedEventArgs.OperationType.Add)); - - if (printer.Settings.PrinterSelected - && printer.Settings.GetValue(SettingsKey.auto_connect)) - { - printer.Connection.Connect(); - } - - return printer; } - return PrinterConfig.EmptyPrinter; + if (printer != null + && printer.Settings.PrinterSelected + && printer.Settings.GetValue(SettingsKey.auto_connect)) + { + printer.Connection.Connect(); + } + + return printer; + } + + public void OpenWorkspace(PartWorkspace workspace) + { + this.OnWorkspacesChanged( + new WorkspacesChangedEventArgs( + workspace, + WorkspacesChangedEventArgs.OperationType.Add)); + + ApplicationController.Instance.Workspaces.Add(workspace); } public async Task OpenAllPrinters() { - foreach (var printerID in ProfileManager.Instance.OpenPrinterIDs) - { - await this.OpenPrinter(printerID); - } + //foreach (var printerID in ProfileManager.Instance.OpenPrinterIDs) + //{ + // await this.OpenPrinter(printerID); + //} + } /// @@ -3206,6 +3214,99 @@ If you experience adhesion problems, please re-run leveling." return Task.CompletedTask; }); + + // Instead of opening printers, we should load open tabs........................ + + // Persist part workspaces + + var history = applicationController.Library.PlatingHistory; + + if (File.Exists(ProfileManager.Instance.OpenTabsPath)) + { + try + { + string openTabsText = File.ReadAllText(ProfileManager.Instance.OpenTabsPath); + var persistedWorkspaces = JsonConvert.DeserializeObject>( + openTabsText, + new ContentStoreConverter(), + new LibraryItemConverter()); + + foreach (var persistedWorkspace in persistedWorkspaces) + { + // Load the actual workspace if content file exists + if (File.Exists(persistedWorkspace.ContentPath)) + { + // Spin up the printer if specified + // Push item to loaded workspaces + + string printerID = persistedWorkspace.PrinterID; + + PartWorkspace workspace = null; + + if (!string.IsNullOrEmpty(printerID) + && ProfileManager.Instance[printerID] != null) + { + + //var workspace = this.OpenWorkspace(printerID, )); + + var itemPrinter = await applicationController.OpenPrinter(persistedWorkspace.PrinterID, false); + + // Add workspace for printer plate + workspace = new PartWorkspace(itemPrinter); + } + else + { + workspace = new PartWorkspace(new BedConfig(history)); + } + + // Load it up + await workspace.SceneContext.LoadContent(new EditContext() { + ContentStore = history, + SourceItem = new FileSystemFileItem(persistedWorkspace.ContentPath) + }); + + if (workspace.Printer != null) + { + workspace.Name = workspace.Printer.Settings.GetValue(SettingsKey.printer_name); + } + else + { + workspace.Name = workspace?.SceneContext.EditContext?.SourceItem?.Name ?? "Unknown"; + } + + applicationController.OpenWorkspace(workspace); + + } + } + } + catch + { + // Create new part tab on failure? + } + } + else + { + // Create new part tab if no existing? + } + + if (applicationController.Workspaces.Count == 0) + { + var workspace = new PartWorkspace(new BedConfig(history)) + { + Name = "New Design".Localize() + }; + + // Load it up + workspace.SceneContext.LoadEmptyContent( + new EditContext() + { + ContentStore = history, + SourceItem = history.NewPlatingItem() + }); + + applicationController.OpenWorkspace(workspace); + } + await applicationController.Tasks.Execute( "Restoring Printers".Localize(), null, @@ -3257,4 +3358,20 @@ If you experience adhesion problems, please re-run leveling." }); } } + + public class ContentStoreConverter : JsonConverter + { + public override bool CanWrite => false; + + public override IContentStore ReadJson(JsonReader reader, Type objectType, IContentStore existingValue, bool hasExistingValue, JsonSerializer serializer) + { + var token = JToken.Load(reader); + + return null; + } + + public override void WriteJson(JsonWriter writer, IContentStore value, JsonSerializer serializer) + { + } + } } \ No newline at end of file diff --git a/MatterControlLib/ApplicationView/BedConfig.cs b/MatterControlLib/ApplicationView/BedConfig.cs index 40afaabc8..3caa20982 100644 --- a/MatterControlLib/ApplicationView/BedConfig.cs +++ b/MatterControlLib/ApplicationView/BedConfig.cs @@ -60,10 +60,12 @@ namespace MatterHackers.MatterControl public View3DConfig RendererOptions { get; } = new View3DConfig(); + [JsonIgnore] public PrinterConfig Printer { get; set; } - public EditContext EditContext { get; private set; } + public EditContext EditContext { get; set; } + [JsonIgnore] public Mesh PrinterShape { get; private set; } public SceneContextViewState ViewState { get; } @@ -346,11 +348,14 @@ namespace MatterHackers.MatterControl } } + [JsonIgnore] public InteractiveScene Scene { get; } = new InteractiveScene(); public GCodeRenderInfo RenderInfo { get; set; } private Mesh _bedMesh; + + [JsonIgnore] public Mesh Mesh { get @@ -414,6 +419,7 @@ namespace MatterHackers.MatterControl private Mesh _buildVolumeMesh; + [JsonIgnore] public Mesh BuildVolumeMesh => _buildVolumeMesh; public bool EditableScene => this.EditContext?.FreezeGCode != true; diff --git a/MatterControlLib/ApplicationView/LibraryItemConverter.cs b/MatterControlLib/ApplicationView/LibraryItemConverter.cs new file mode 100644 index 000000000..7524a2d02 --- /dev/null +++ b/MatterControlLib/ApplicationView/LibraryItemConverter.cs @@ -0,0 +1,77 @@ +/* +Copyright (c) 2018, Lars Brubaker, 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 Newtonsoft.Json; + +namespace MatterHackers.MatterControl +{ + using MatterHackers.MatterControl.Library; + using Newtonsoft.Json.Linq; + + public class LibraryItemConverter : JsonConverter + { + public override bool CanWrite => false; + + public override ILibraryItem ReadJson(JsonReader reader, Type objectType, ILibraryItem existingValue, bool hasExistingValue, JsonSerializer serializer) + { + var jsonObject = JObject.Load(reader); + + var item = new DummyItem(); + + serializer.Populate(jsonObject.CreateReader(), item); + + return item; + } + + public override void WriteJson(JsonWriter writer, ILibraryItem value, JsonSerializer serializer) + { + } + } + + public class DummyItem : ILibraryItem + { + public string ID { get; set; } + + public string Name { get; set; } + + public bool IsProtected { get; set; } + + public bool IsVisible { get; set; } + + public DateTime DateModified { get; set; } + + public DateTime DateCreated { get; set; } + + public string Path { get; set; } + + public string AssetPath { get; set; } + } + +} \ No newline at end of file diff --git a/MatterControlLib/ApplicationView/PartWorkspace.cs b/MatterControlLib/ApplicationView/PartWorkspace.cs index e5ff0e5cf..a75f1e82d 100644 --- a/MatterControlLib/ApplicationView/PartWorkspace.cs +++ b/MatterControlLib/ApplicationView/PartWorkspace.cs @@ -27,11 +27,43 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using Newtonsoft.Json; + namespace MatterHackers.MatterControl { public class PartWorkspace { + private BedConfig _sceneContext { get; } + + public PartWorkspace() + { + } + + public PartWorkspace(PrinterConfig printer) + : this (printer.Bed) + { + this.Printer = printer; + this.PrinterID = printer.Settings.ID; + } + + public PartWorkspace(BedConfig bedConfig) + { + _sceneContext = bedConfig; + Name = _sceneContext.EditContext?.SourceItem?.Name ?? "Unknown"; + } + public string Name { get; set; } - public BedConfig SceneContext { get; set; } + + [JsonIgnore] + public BedConfig SceneContext => _sceneContext; + + public EditContext EditContext { get; set; } + + public string PrinterID { get; set; } + + [JsonIgnore] + public PrinterConfig Printer { get; } + + public string ContentPath { get; set; } } } \ No newline at end of file diff --git a/MatterControlLib/ApplicationView/PrinterConfig.cs b/MatterControlLib/ApplicationView/PrinterConfig.cs index 72bf45ac7..bb67826e8 100644 --- a/MatterControlLib/ApplicationView/PrinterConfig.cs +++ b/MatterControlLib/ApplicationView/PrinterConfig.cs @@ -34,16 +34,13 @@ using MatterHackers.MatterControl.SlicerConfiguration; namespace MatterHackers.MatterControl { - using System.IO; using System.Threading; using MatterHackers.Agg; - using MatterHackers.DataConverters3D; using MatterHackers.Localizations; - using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.PrinterCommunication; using MatterHackers.MatterControl.SlicerConfiguration.MappingClasses; - using MatterHackers.MeshVisualizer; using MatterHackers.VectorMath; + using Newtonsoft.Json; public class PrinterConfig : IDisposable { @@ -55,6 +52,7 @@ namespace MatterHackers.MatterControl public static PrinterConfig EmptyPrinter { get; } = new PrinterConfig(); + [JsonIgnore] public EngineMappingsMatterSlice EngineMappingsMatterSlice { get; } // heating status @@ -173,6 +171,7 @@ namespace MatterHackers.MatterControl } } + [JsonIgnore] public PrinterConnection Connection { get; } public string PrinterConnectionStatus diff --git a/MatterControlLib/Library/Widgets/LibraryWidget.cs b/MatterControlLib/Library/Widgets/LibraryWidget.cs index 51d787e27..25a0d553e 100644 --- a/MatterControlLib/Library/Widgets/LibraryWidget.cs +++ b/MatterControlLib/Library/Widgets/LibraryWidget.cs @@ -764,10 +764,9 @@ namespace MatterHackers.MatterControl.PrintLibrary if (selectedLibraryItems.FirstOrDefault() is ILibraryItem firstItem && ApplicationController.Instance.Library.ActiveContainer is ILibraryWritableContainer writableContainer) { - var workspace = new PartWorkspace() + var workspace = new PartWorkspace(new BedConfig(ApplicationController.Instance.Library.PlatingHistory)) { Name = firstItem.Name, - SceneContext = new BedConfig(ApplicationController.Instance.Library.PlatingHistory) }; ApplicationController.Instance.Workspaces.Add(workspace); diff --git a/MatterControlLib/PartPreviewWindow/MainViewWidget.cs b/MatterControlLib/PartPreviewWindow/MainViewWidget.cs index a8fa99820..1506d0ef8 100644 --- a/MatterControlLib/PartPreviewWindow/MainViewWidget.cs +++ b/MatterControlLib/PartPreviewWindow/MainViewWidget.cs @@ -166,11 +166,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow Padding = new BorderDouble(15, 0), }); - if (ApplicationController.Instance.Workspaces.Count == 0) - { - this.CreatePartTab().ConfigureAwait(false); - } - string tabKey = ApplicationController.Instance.MainTabKey; if (string.IsNullOrEmpty(tabKey)) @@ -261,7 +256,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow // Register listeners PrinterSettings.AnyPrinterSettingChanged += Printer_SettingChanged; - ApplicationController.Instance.OpenPrintersChanged += OpenPrinters_Changed; + ApplicationController.Instance.WorkspacesChanged += Workspaces_Changed; ApplicationController.Instance.Tasks.TasksChanged += Tasks_TasksChanged; tabControl.ActiveTabChanged += TabControl_ActiveTabChanged; @@ -279,10 +274,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { var history = ApplicationController.Instance.Library.PlatingHistory; - var workspace = new PartWorkspace() + var workspace = new PartWorkspace(new BedConfig(history)) { Name = Path.GetFileName(filePath), - SceneContext = new BedConfig(history) }; ApplicationController.Instance.Workspaces.Add(workspace); @@ -392,21 +386,29 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } } - private void OpenPrinters_Changed(object sender, OpenPrintersChangedEventArgs e) + private void Workspaces_Changed(object sender, WorkspacesChangedEventArgs e) { - var activePrinter = e.Printer; + var activePrinter = e.Workspace.Printer; - if (e.Operation == OpenPrintersChangedEventArgs.OperationType.Add) + if (e.Operation == WorkspacesChangedEventArgs.OperationType.Add) { - if (activePrinter.Settings.PrinterSelected) - { // Create and switch to new printer tab - tabControl.ActiveTab = this.CreatePrinterTab(activePrinter, theme); + if (activePrinter?.Settings.PrinterSelected == true) + { + tabControl.ActiveTab = this.CreatePrinterTab(activePrinter, theme); + } + else + { + tabControl.ActiveTab = this.CreatePartTab(e.Workspace); + } + tabControl.RefreshTabPointers(); - } } else { + // TODO: Do the work to select the part *OR* printer tab and remove + System.Diagnostics.Debugger.Break(); + // Close existing printer tabs if (tabControl.AllTabs.FirstOrDefault(t => t.TabContent is PrinterTabPage printerTab && printerTab.printer.Settings.ID == activePrinter.Settings.ID) is ITab tab @@ -570,10 +572,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { var history = ApplicationController.Instance.Library.PlatingHistory; - var workspace = new PartWorkspace() + var workspace = new PartWorkspace(new BedConfig(history)) { Name = "New Design".Localize() + (partCount == 0 ? "" : $" ({partCount})"), - SceneContext = new BedConfig(history) }; partCount++; @@ -622,7 +623,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow // Unregister listeners PrinterSettings.AnyPrinterSettingChanged -= Printer_SettingChanged; UserSettings.Instance.SettingChanged -= SetLinkButtonsVisibility; - ApplicationController.Instance.OpenPrintersChanged -= OpenPrinters_Changed; + ApplicationController.Instance.WorkspacesChanged -= Workspaces_Changed; ApplicationController.Instance.Tasks.TasksChanged -= Tasks_TasksChanged; ApplicationController.Instance.ShellFileOpened -= Instance_OpenNewFile; tabControl.ActiveTabChanged -= TabControl_ActiveTabChanged; diff --git a/MatterControlLib/PartPreviewWindow/SelectedObjectPanel.cs b/MatterControlLib/PartPreviewWindow/SelectedObjectPanel.cs index 21b9388ce..aeed0180c 100644 --- a/MatterControlLib/PartPreviewWindow/SelectedObjectPanel.cs +++ b/MatterControlLib/PartPreviewWindow/SelectedObjectPanel.cs @@ -323,6 +323,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow private void ShowObjectEditor((IObject3DEditor editor, IObject3D item, string displayName) scopeItem, IObject3D rootSelection, bool allowOperations = true) { + // TODO: Some editors make blind assumptions about context when using DragDropData for reference. Remove DragDropData from PublicPropertiesEditor and + // similar widgets to ensure they use the context they're hosted in rather than cheating with the DragDropData reference. Until then this guard + // prevents invoking editors that depend on DragDropData while it's null + if (ApplicationController.Instance.DragDropData?.View3DWidget == null) + { + return; + } + var selectedItem = scopeItem.item; var selectedItemType = selectedItem.GetType(); diff --git a/MatterControlLib/RootSystemWindow.cs b/MatterControlLib/RootSystemWindow.cs index 167bf3a17..c87f367f0 100644 --- a/MatterControlLib/RootSystemWindow.cs +++ b/MatterControlLib/RootSystemWindow.cs @@ -30,6 +30,7 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Diagnostics; using System.IO; +using System.Linq; using MatterHackers.Agg; using MatterHackers.Agg.Platform; using MatterHackers.Agg.UI; @@ -38,7 +39,9 @@ using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.PrinterCommunication; using MatterHackers.MatterControl.PrintQueue; using MatterHackers.MatterControl.SettingsManagement; +using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.VectorMath; +using Newtonsoft.Json; namespace MatterHackers.MatterControl { @@ -295,11 +298,40 @@ namespace MatterHackers.MatterControl StyledMessageBox.MessageType.YES_NO_WITHOUT_HIGHLIGHT); }); } - else if(!ApplicationController.Instance.ApplicationExiting) + else if (!ApplicationController.Instance.ApplicationExiting) { // cancel the close so that we can save all our active work spaces eventArgs.Cancel = true; + var workspaces = ApplicationController.Instance.Workspaces.Select(w => + { + if (w.Printer == null) + { + return new PartWorkspace(w.SceneContext) + { + ContentPath = w.SceneContext.EditContext?.SourceFilePath, + }; + } + else + { + return new PartWorkspace(w.Printer) + { + ContentPath = w.SceneContext.EditContext?.SourceFilePath, + }; + } + }); + + // Persist part workspaces + File.WriteAllText( + ProfileManager.Instance.OpenTabsPath, + JsonConvert.SerializeObject( + workspaces, + Formatting.Indented, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + })); + UiThread.RunOnIdle(async () => { var application = ApplicationController.Instance; diff --git a/MatterControlLib/SlicerConfiguration/Settings/ProfileManager.cs b/MatterControlLib/SlicerConfiguration/Settings/ProfileManager.cs index a28ac07a6..8493c178f 100644 --- a/MatterControlLib/SlicerConfiguration/Settings/ProfileManager.cs +++ b/MatterControlLib/SlicerConfiguration/Settings/ProfileManager.cs @@ -93,6 +93,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration [JsonIgnore] public string ProfileThemeSetPath => Path.Combine(UserProfilesDirectory, "themeset.json"); + [JsonIgnore] + public string OpenTabsPath => Path.Combine(UserProfilesDirectory, "opentabs.json"); + /// /// The user specific path to the Profiles document /// @@ -233,15 +236,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration // Lazy load from db if null if (profileIDsBackingField == null) { - string profileIDs = UserSettings.Instance.get($"ActiveProfileIDs-{UserName}"); - try - { - profileIDsBackingField = JsonConvert.DeserializeObject>(profileIDs); - } - catch - { - profileIDsBackingField = new List(); - } + profileIDsBackingField = new List(); } return profileIDsBackingField; @@ -251,28 +246,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration [JsonIgnore] public IEnumerable OpenPrinterIDs => _activeProfileIDs; - public void OpenPrinter(string printerID) - { - try - { - if (!_activeProfileIDs.Contains(printerID)) - { - _activeProfileIDs.Add(printerID); - UserSettings.Instance.set($"ActiveProfileIDs-{UserName}", JsonConvert.SerializeObject(_activeProfileIDs)); - } - } - catch - { - } - } - public void ClosePrinter(string printerID) { try { - _activeProfileIDs.Remove(printerID); - UserSettings.Instance.set($"ActiveProfileIDs-{UserName}", JsonConvert.SerializeObject(_activeProfileIDs)); - // Unregister listener if (ApplicationController.Instance.ActivePrinters.FirstOrDefault(p => p.Settings.ID == printerID) is PrinterConfig printer) { diff --git a/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs b/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs index 9e5cdb613..75bf5f04c 100644 --- a/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs +++ b/Tests/MatterControl.Tests/MatterControl/MatterControlUtilities.cs @@ -637,7 +637,7 @@ namespace MatterHackers.MatterControl.Tests.Automation /// The first active printer public static PrinterConfig FirstPrinter(this AutomationRunner testRunner) { - Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count, "FirstPrinter() is only valid in single printer scenarios"); + Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "FirstPrinter() is only valid in single printer scenarios"); return ApplicationController.Instance.ActivePrinters.First(); }