Revise tab ordering and persistence logic

- Issue MatterHackers/MCCentral#4555
This commit is contained in:
John Lewin 2018-12-07 18:41:32 -08:00
parent 980b9e6236
commit aae2ffdf76
11 changed files with 347 additions and 99 deletions

View file

@ -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<PrinterConfig> ActivePrinters => _activePrinters;
public IEnumerable<PrinterConfig> 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<PrinterConfig> _activePrinters = new List<PrinterConfig>();
//// A list of printers which are open (i.e. displaying a tab) on this instance of MatterControl
//private List<PrinterConfig> _activePrinters = new List<PrinterConfig>();
private Dictionary<Type, HashSet<IObject3DEditor>> objectEditorsByType;
@ -395,7 +390,7 @@ namespace MatterHackers.MatterControl
public RootedObjectEventHandler DoneReloadingAll = new RootedObjectEventHandler();
public RootedObjectEventHandler ActiveProfileModified = new RootedObjectEventHandler();
public event EventHandler<OpenPrintersChangedEventArgs> OpenPrintersChanged;
public event EventHandler<WorkspacesChangedEventArgs> WorkspacesChanged;
public static Action WebRequestFailed;
public static Action WebRequestSucceeded;
@ -412,9 +407,9 @@ namespace MatterHackers.MatterControl
public static Func<string, Task<Dictionary<string, string>>> 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<PrinterConfig>();
//_activePrinters = new List<PrinterConfig>();
};
this.RebuildSceneOperations(this.Theme);
@ -1811,39 +1810,48 @@ namespace MatterHackers.MatterControl
public async Task<PrinterConfig> 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<bool>(SettingsKey.auto_connect))
{
printer.Connection.Connect();
}
return printer;
}
return PrinterConfig.EmptyPrinter;
if (printer != null
&& printer.Settings.PrinterSelected
&& printer.Settings.GetValue<bool>(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);
//}
}
/// <summary>
@ -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<List<PartWorkspace>>(
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<IContentStore>
{
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)
{
}
}
}

View file

@ -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;

View file

@ -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<ILibraryItem>
{
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; }
}
}

View file

@ -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; }
}
}

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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();

View file

@ -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;

View file

@ -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");
/// <summary>
/// The user specific path to the Profiles document
/// </summary>
@ -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<List<string>>(profileIDs);
}
catch
{
profileIDsBackingField = new List<string>();
}
profileIDsBackingField = new List<string>();
}
return profileIDsBackingField;
@ -251,28 +246,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
[JsonIgnore]
public IEnumerable<string> 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)
{

View file

@ -637,7 +637,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
/// <returns>The first active printer</returns>
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();
}