diff --git a/ActionBar/PrintActionRow.cs b/ActionBar/PrintActionRow.cs index 1dfad24a5..e37fb9bea 100644 --- a/ActionBar/PrintActionRow.cs +++ b/ActionBar/PrintActionRow.cs @@ -80,7 +80,7 @@ namespace MatterHackers.MatterControl.ActionBar AddChildElements(buttonFactory, parentWidget); // Add Handlers - PrinterConnection.Instance.ActivePrintItemChanged.RegisterEvent(onStateChanged, ref unregisterEvents); + ApplicationController.Instance.ActivePrintItemChanged.RegisterEvent(onStateChanged, ref unregisterEvents); PrinterConnection.Instance.CommunicationStateChanged.RegisterEvent(onStateChanged, ref unregisterEvents); ProfileManager.ProfilesListChanged.RegisterEvent(onStateChanged, ref unregisterEvents); } @@ -383,7 +383,7 @@ namespace MatterHackers.MatterControl.ActionBar { UiThread.RunOnIdle(() => { - PrinterConnection.Instance.PrintActivePartIfPossible(); + ApplicationController.Instance.PrintActivePartIfPossible(); }); } diff --git a/ActionBar/PrintStatusRow.cs b/ActionBar/PrintStatusRow.cs index 8a8e67bd4..58bec18ea 100644 --- a/ActionBar/PrintStatusRow.cs +++ b/ActionBar/PrintStatusRow.cs @@ -59,7 +59,7 @@ namespace MatterHackers.MatterControl.ActionBar AddChildElements(); - PrinterConnection.Instance.ActivePrintItemChanged.RegisterEvent((s, e) => + ApplicationController.Instance.ActivePrintItemChanged.RegisterEvent((s, e) => { UpdatePrintItemName(); UpdatePrintStatus(); @@ -201,9 +201,9 @@ namespace MatterHackers.MatterControl.ActionBar private void UpdatePrintItemName() { - if (PrinterConnection.Instance.ActivePrintItem != null) + if (ApplicationController.Instance.ActivePrintItem != null) { - this.activePrintName.Text = PrinterConnection.Instance.ActivePrintItem.GetFriendlyName(); + this.activePrintName.Text = ApplicationController.Instance.ActivePrintItem.GetFriendlyName(); } else { @@ -216,7 +216,7 @@ namespace MatterHackers.MatterControl.ActionBar string printLabel = "Next Print".Localize() + ":"; string printerStatus = activePrintStatus.Text; - if (PrinterConnection.Instance.ActivePrintItem != null) + if (ApplicationController.Instance.ActivePrintItem != null) { int totalSecondsInPrint = PrinterConnection.Instance.TotalSecondsInPrint; diff --git a/ActionBar/PrinterSelector.cs b/ActionBar/PrinterSelector.cs index fb8417c42..4294f128d 100644 --- a/ActionBar/PrinterSelector.cs +++ b/ActionBar/PrinterSelector.cs @@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Linq; +using MatterHackers.Agg; using MatterHackers.Agg.PlatformAbstract; using MatterHackers.Agg.UI; using MatterHackers.Localizations; diff --git a/ActionBar/TouchScreenPrintStatusRow.cs b/ActionBar/TouchScreenPrintStatusRow.cs index 6d1653fd5..b37275c4b 100644 --- a/ActionBar/TouchScreenPrintStatusRow.cs +++ b/ActionBar/TouchScreenPrintStatusRow.cs @@ -64,7 +64,7 @@ namespace MatterHackers.MatterControl.ActionBar AddChildElements(); - PrinterConnection.Instance.ActivePrintItemChanged.RegisterEvent((s, e) => + ApplicationController.Instance.ActivePrintItemChanged.RegisterEvent((s, e) => { UpdatePrintItemName(); UpdatePrintStatus(); @@ -80,7 +80,7 @@ namespace MatterHackers.MatterControl.ActionBar UpdatePrintStatus(); }, ref unregisterEvents); - PrinterConnection.Instance.ActivePrintItemChanged.RegisterEvent(onActivePrintItemChanged, ref unregisterEvents); + ApplicationController.Instance.ActivePrintItemChanged.RegisterEvent(onActivePrintItemChanged, ref unregisterEvents); onActivePrintItemChanged(null, null); } @@ -245,7 +245,7 @@ namespace MatterHackers.MatterControl.ActionBar activePrintPreviewImage.ItemWrapper.SlicingOutputMessage -= PrintItem_SlicingOutputMessage; } - activePrintPreviewImage.ItemWrapper = PrinterConnection.Instance.ActivePrintItem; + activePrintPreviewImage.ItemWrapper = ApplicationController.Instance.ActivePrintItem; // then hook up our new part if (activePrintPreviewImage.ItemWrapper != null) @@ -291,9 +291,9 @@ namespace MatterHackers.MatterControl.ActionBar private void UpdatePrintItemName() { - if (PrinterConnection.Instance.ActivePrintItem != null) + if (ApplicationController.Instance.ActivePrintItem != null) { - this.activePrintName.Text = PrinterConnection.Instance.ActivePrintItem.GetFriendlyName(); + this.activePrintName.Text = ApplicationController.Instance.ActivePrintItem.GetFriendlyName(); } else { @@ -303,7 +303,7 @@ namespace MatterHackers.MatterControl.ActionBar private void UpdatePrintStatus() { - if (PrinterConnection.Instance.ActivePrintItem != null) + if (ApplicationController.Instance.ActivePrintItem != null) { int totalSecondsInPrint = PrinterConnection.Instance.TotalSecondsInPrint; diff --git a/ApplicationView/ApplicationController.cs b/ApplicationView/ApplicationController.cs index 57e4752e8..a49b24787 100644 --- a/ApplicationView/ApplicationController.cs +++ b/ApplicationView/ApplicationController.cs @@ -45,6 +45,7 @@ using Newtonsoft.Json; namespace MatterHackers.MatterControl { + using System.IO.Compression; using System.Net; using System.Reflection; using System.Threading; @@ -52,8 +53,10 @@ namespace MatterHackers.MatterControl using Agg.Image; using CustomWidgets; using MatterHackers.DataConverters3D; + using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling; using MatterHackers.MatterControl.Library; using MatterHackers.MatterControl.PartPreviewWindow; + using MatterHackers.SerialPortCommunication; using MatterHackers.VectorMath; using PrintHistory; using SettingsManagement; @@ -260,7 +263,7 @@ namespace MatterHackers.MatterControl string mcxPath = Path.Combine(platingDirectory, now + ".mcx"); - PrinterConnection.Instance.ActivePrintItem = new PrintItemWrapper(new PrintItem(now, mcxPath)); + ApplicationController.Instance.ActivePrintItem = new PrintItemWrapper(new PrintItem(now, mcxPath)); File.WriteAllText(mcxPath, new Object3D().ToJson()); } @@ -527,6 +530,19 @@ namespace MatterHackers.MatterControl this.InitializeLibrary(); + PrinterConnection.Instance.ConnectionSucceeded.RegisterEvent((s, e) => + { + // run the print leveling wizard if we need to for this printer + if (ActiveSliceSettings.Instance.GetValue(SettingsKey.print_leveling_required_to_print) + || ActiveSliceSettings.Instance.GetValue(SettingsKey.print_leveling_enabled)) + { + PrintLevelingData levelingData = ActiveSliceSettings.Instance.Helpers.GetPrintLevelingData(); + if (levelingData?.HasBeenRunAndEnabled() != true) + { + UiThread.RunOnIdle(LevelWizardBase.ShowPrintLevelWizard); + } + } + }, ref unregisterEvents); } @@ -950,7 +966,7 @@ namespace MatterHackers.MatterControl { if (PrinterConnection.Instance.CommunicationState == CommunicationStates.Connected) { - PrinterConnection.Instance.PrintActivePartIfPossible(); + ApplicationController.Instance.PrintActivePartIfPossible(); } }, ref unregisterEvent); } @@ -1098,5 +1114,220 @@ namespace MatterHackers.MatterControl return Enumerable.Empty(); } + + private PrintItemWrapper activePrintItem; + + public PrintItemWrapper ActivePrintItem + { + get + { + return this.activePrintItem; + } + set + { + if (!PrinterConnection.Instance.PrinterIsPrinting + && !PrinterConnection.Instance.PrinterIsPaused + && this.activePrintItem != value) + { + this.activePrintItem = value; + if (PrinterConnection.Instance.CommunicationState == CommunicationStates.FinishedPrint) + { + PrinterConnection.Instance.CommunicationState = CommunicationStates.Connected; + } + + PrinterConnection.Instance.activePrintItem = value; + + OnActivePrintItemChanged(null); + } + } + } + + private void OnActivePrintItemChanged(EventArgs e) + { + ActivePrintItemChanged.CallEvents(this, e); + } + + private string doNotAskAgainMessage = "Don't remind me again".Localize(); + + public async void PrintActivePart(bool overrideAllowGCode = false) + { + try + { + // If leveling is required or is currently on + if (ActiveSliceSettings.Instance.GetValue(SettingsKey.print_leveling_required_to_print) + || ActiveSliceSettings.Instance.GetValue(SettingsKey.print_leveling_enabled)) + { + PrintLevelingData levelingData = ActiveSliceSettings.Instance.Helpers.GetPrintLevelingData(); + if (levelingData?.HasBeenRunAndEnabled() != true) + { + LevelWizardBase.ShowPrintLevelWizard(); + return; + } + } + + // Save any pending changes before starting the print + await ApplicationController.Instance.ActiveView3DWidget.PersistPlateIfNeeded(); + + if (activePrintItem != null) + { + string pathAndFile = activePrintItem.FileLocation; + if (ActiveSliceSettings.Instance.GetValue(SettingsKey.has_sd_card_reader) + && pathAndFile == QueueData.SdCardFileName) + { + PrinterConnection.Instance.StartSdCardPrint(); + } + else if (ActiveSliceSettings.Instance.IsValid()) + { + if (File.Exists(pathAndFile)) + { + // clear the output cache prior to starting a print + PrinterOutputCache.Instance.Clear(); + + string hideGCodeWarning = ApplicationSettings.Instance.get(ApplicationSettingsKey.HideGCodeWarning); + + if (Path.GetExtension(pathAndFile).ToUpper() == ".GCODE" + && hideGCodeWarning == null + && !overrideAllowGCode) + { + CheckBox hideGCodeWarningCheckBox = new CheckBox(doNotAskAgainMessage); + hideGCodeWarningCheckBox.TextColor = ActiveTheme.Instance.PrimaryTextColor; + hideGCodeWarningCheckBox.Margin = new BorderDouble(top: 6, left: 6); + hideGCodeWarningCheckBox.HAnchor = Agg.UI.HAnchor.ParentLeft; + hideGCodeWarningCheckBox.Click += (sender, e) => + { + if (hideGCodeWarningCheckBox.Checked) + { + ApplicationSettings.Instance.set(ApplicationSettingsKey.HideGCodeWarning, "true"); + } + else + { + ApplicationSettings.Instance.set(ApplicationSettingsKey.HideGCodeWarning, null); + } + }; + + UiThread.RunOnIdle(() => StyledMessageBox.ShowMessageBox(onConfirmPrint, gcodeWarningMessage, "Warning - GCode file".Localize(), new GuiWidget[] { new VerticalSpacer(), hideGCodeWarningCheckBox }, StyledMessageBox.MessageType.YES_NO)); + } + else + { + PrinterConnection.Instance.CommunicationState = CommunicationStates.PreparingToPrint; + PrintItemWrapper partToPrint = activePrintItem; + SlicingQueue.Instance.QueuePartForSlicing(partToPrint); + partToPrint.SlicingDone += partToPrint_SliceDone; + } + } + } + } + } + catch (Exception) + { + } + } + + private string gcodeWarningMessage = "The file you are attempting to print is a GCode file.\n\nIt is recommended that you only print Gcode files known to match your printer's configuration.\n\nAre you sure you want to print this GCode file?".Localize(); + + private void onConfirmPrint(bool messageBoxResponse) + { + if (messageBoxResponse) + { + PrinterConnection.Instance.CommunicationState = CommunicationStates.PreparingToPrint; + PrintItemWrapper partToPrint = activePrintItem; + SlicingQueue.Instance.QueuePartForSlicing(partToPrint); + partToPrint.SlicingDone += partToPrint_SliceDone; + } + } + + + public void PrintActivePartIfPossible(bool overrideAllowGCode = false) + { + if (PrinterConnection.Instance.CommunicationState == CommunicationStates.Connected || PrinterConnection.Instance.CommunicationState == CommunicationStates.FinishedPrint) + { + PrintActivePart(overrideAllowGCode); + } + } + + private void partToPrint_SliceDone(object sender, EventArgs e) + { + PrintItemWrapper partToPrint = sender as PrintItemWrapper; + if (partToPrint != null) + { + partToPrint.SlicingDone -= partToPrint_SliceDone; + string gcodePathAndFileName = partToPrint.GetGCodePathAndFileName(); + if (gcodePathAndFileName != "") + { + bool originalIsGCode = Path.GetExtension(partToPrint.FileLocation).ToUpper() == ".GCODE"; + if (File.Exists(gcodePathAndFileName)) + { + // Create archive point for printing attempt + if (Path.GetExtension(partToPrint.FileLocation).ToUpper() == ".MCX") + { + // TODO: We should zip mcx and settings when starting a print + string platingDirectory = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, "PrintHistory"); + Directory.CreateDirectory(platingDirectory); + + string now = DateTime.Now.ToString("yyyyMMdd-HHmmss"); + string archivePath = Path.Combine(platingDirectory, now + ".zip"); + + using (var file = File.OpenWrite(archivePath)) + using (var zip = new ZipArchive(file, ZipArchiveMode.Create)) + { + zip.CreateEntryFromFile(partToPrint.FileLocation, "PrinterPlate.mcx"); + zip.CreateEntryFromFile(ActiveSliceSettings.Instance.DocumentPath, ActiveSliceSettings.Instance.GetValue(SettingsKey.printer_name) + ".printer"); + zip.CreateEntryFromFile(gcodePathAndFileName, "sliced.gcode"); + } + } + + // read the last few k of the file and see if it says "filament used". We use this marker to tell if the file finished writing + if (originalIsGCode) + { + PrinterConnection.Instance.StartPrint(gcodePathAndFileName); + return; + } + else + { + int bufferSize = 32000; + using (Stream fileStream = new FileStream(gcodePathAndFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + byte[] buffer = new byte[bufferSize]; + fileStream.Seek(Math.Max(0, fileStream.Length - bufferSize), SeekOrigin.Begin); + int numBytesRead = fileStream.Read(buffer, 0, bufferSize); + fileStream.Close(); + + string fileEnd = System.Text.Encoding.UTF8.GetString(buffer); + if (fileEnd.Contains("filament used")) + { + PrinterConnection.Instance.StartPrint(gcodePathAndFileName); + return; + } + } + } + } + + PrinterConnection.Instance.CommunicationState = CommunicationStates.Connected; + } + } + } + + // TODO: this must be wired up to PrinterConnection.ErrorReported + public void PrinterReportsError(object sender, EventArgs e) + { + var foundStringEventArgs = e as FoundStringEventArgs; + if (foundStringEventArgs != null) + { + string message = "Your printer is reporting a hardware Error. This may prevent your printer from functioning properly.".Localize() + + "\n" + + "\n" + + "Error Reported".Localize() + ":" + + $" \"{foundStringEventArgs.LineToCheck}\"."; + UiThread.RunOnIdle(() => + StyledMessageBox.ShowMessageBox(null, message, "Printer Hardware Error".Localize()) + ); + } + } + + + + + public RootedObjectEventHandler ActivePrintItemChanged = new RootedObjectEventHandler(); + } } \ No newline at end of file diff --git a/ApplicationView/TouchscreenTabView.cs b/ApplicationView/TouchscreenTabView.cs index 428c70fc6..98058bb7b 100644 --- a/ApplicationView/TouchscreenTabView.cs +++ b/ApplicationView/TouchscreenTabView.cs @@ -86,7 +86,7 @@ namespace MatterHackers.MatterControl "Preview".Localize().ToUpper(), generator: () => { - partPreviewContainer = new PartPreviewContent(PrinterConnection.Instance.ActivePrintItem, View3DWidget.WindowMode.Embeded, View3DWidget.AutoRotate.Enabled, View3DWidget.OpenMode.Viewing); + partPreviewContainer = new PartPreviewContent(ApplicationController.Instance.ActivePrintItem, View3DWidget.WindowMode.Embeded, View3DWidget.AutoRotate.Enabled, View3DWidget.OpenMode.Viewing); return partPreviewContainer; }); @@ -179,12 +179,12 @@ namespace MatterHackers.MatterControl SetUpdateNotification(this, null); - PrinterConnection.Instance.ActivePrintItemChanged.RegisterEvent((s, e) => + ApplicationController.Instance.ActivePrintItemChanged.RegisterEvent((s, e) => { // ReloadPartPreview UiThread.RunOnIdle(() => { - partPreviewContainer?.Reload(PrinterConnection.Instance.ActivePrintItem); + partPreviewContainer?.Reload(ApplicationController.Instance.ActivePrintItem); }, 1); }, ref unregisterEvents); diff --git a/ApplicationView/WidescreenPanel.cs b/ApplicationView/WidescreenPanel.cs index 6859445f4..eb7a2b328 100644 --- a/ApplicationView/WidescreenPanel.cs +++ b/ApplicationView/WidescreenPanel.cs @@ -52,7 +52,7 @@ namespace MatterHackers.MatterControl this.Name = "WidescreenPanel"; // HACK: Long term we need a better solution which does not rely on ActivePrintItem/PrintItemWrapper - if (PrinterConnection.Instance.ActivePrintItem == null) + if (ApplicationController.Instance.ActivePrintItem == null) { ApplicationController.Instance.ClearPlate(); } @@ -75,7 +75,7 @@ namespace MatterHackers.MatterControl }); // put in the right column - library3DViewSplitter.Panel2.AddChild(new PartPreviewContent(PrinterConnection.Instance.ActivePrintItem, View3DWidget.WindowMode.Embeded, View3DWidget.AutoRotate.Disabled) + library3DViewSplitter.Panel2.AddChild(new PartPreviewContent(ApplicationController.Instance.ActivePrintItem, View3DWidget.WindowMode.Embeded, View3DWidget.AutoRotate.Disabled) { VAnchor = VAnchor.ParentBottom | VAnchor.ParentTop, HAnchor = HAnchor.ParentLeft | HAnchor.ParentRight diff --git a/CustomWidgets/PrintProgressBarWidget.cs b/CustomWidgets/PrintProgressBarWidget.cs index 0e2041798..cbdacead8 100644 --- a/CustomWidgets/PrintProgressBarWidget.cs +++ b/CustomWidgets/PrintProgressBarWidget.cs @@ -131,7 +131,7 @@ namespace MatterHackers.MatterControl }; AddChild(clickOverlay); - PrinterConnection.Instance.ActivePrintItemChanged.RegisterEvent(Instance_PrintItemChanged, ref unregisterEvents); + ApplicationController.Instance.ActivePrintItemChanged.RegisterEvent(Instance_PrintItemChanged, ref unregisterEvents); PrinterConnection.Instance.CommunicationStateChanged.RegisterEvent(Instance_PrintItemChanged, ref unregisterEvents); SetThemedColors(); @@ -182,7 +182,7 @@ namespace MatterHackers.MatterControl private void UpdatePrintStatus() { - if (PrinterConnection.Instance.ActivePrintItem == null) + if (ApplicationController.Instance.ActivePrintItem == null) { printTimeElapsed.Text = string.Format(""); printTimeRemaining.Text = string.Format(""); diff --git a/CustomWidgets/PrintingWindow.cs b/CustomWidgets/PrintingWindow.cs index 7747071ff..4a7520e1a 100644 --- a/CustomWidgets/PrintingWindow.cs +++ b/CustomWidgets/PrintingWindow.cs @@ -633,7 +633,7 @@ namespace MatterHackers.MatterControl.CustomWidgets progressContainer.AddChild(printerName); - partName = new TextWidget(PrinterConnection.Instance.ActivePrintItem.GetFriendlyName(), pointSize: 16, textColor: ActiveTheme.Instance.PrimaryTextColor) + partName = new TextWidget(ApplicationController.Instance.ActivePrintItem.GetFriendlyName(), pointSize: 16, textColor: ActiveTheme.Instance.PrimaryTextColor) { HAnchor = HAnchor.ParentCenter, MinimumSize = new Vector2(maxTextWidth, MinimumSize.y), diff --git a/History/PrintHistoryData.cs b/History/PrintHistoryData.cs index 8ac698658..c61223afc 100644 --- a/History/PrintHistoryData.cs +++ b/History/PrintHistoryData.cs @@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl.PrintHistory { static PrintTask lastPrintTask; - public static void CheckIfNeedToRecoverPrint(object sender, EventArgs e) + public static void CheckIfNeedToRecoverPrint() { string recoverPrint = "Recover Print".Localize(); string cancelRecovery = "Cancel".Localize(); @@ -112,8 +112,11 @@ namespace MatterHackers.MatterControl.PrintHistory if (instance == null) { instance = new PrintHistoryData(); - PrinterConnection.Instance.ConnectionSucceeded.RegisterEvent(PrintRecovery.CheckIfNeedToRecoverPrint, ref unregisterEvents); - } + PrinterConnection.Instance.ConnectionSucceeded.RegisterEvent((s, e) => + { + UiThread.RunOnIdle(PrintRecovery.CheckIfNeedToRecoverPrint); + }, ref unregisterEvents); + } return instance; } } diff --git a/History/PrintHistoryListItem.cs b/History/PrintHistoryListItem.cs index 54780a3ac..e7db2f7d1 100644 --- a/History/PrintHistoryListItem.cs +++ b/History/PrintHistoryListItem.cs @@ -27,18 +27,18 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using System; +using System.Globalization; +using System.IO; using MatterHackers.Agg; using MatterHackers.Agg.UI; using MatterHackers.Agg.VertexSource; using MatterHackers.Localizations; using MatterHackers.MatterControl.CustomWidgets; using MatterHackers.MatterControl.DataStorage; +using MatterHackers.MatterControl.Library; using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.PrintQueue; -using System; -using System.Globalization; -using System.IO; -using MatterHackers.MatterControl.Library; namespace MatterHackers.MatterControl.PrintHistory { @@ -239,7 +239,7 @@ namespace MatterHackers.MatterControl.PrintHistory { QueueData.Instance.AddItem(new PrintItemWrapper(printTask.PrintItemId), 0); - PrinterCommunication.PrinterConnection.Instance.PrintActivePartIfPossible(); + ApplicationController.Instance.PrintActivePartIfPossible(); } else { diff --git a/Library/Providers/SDCard/SDCardContainer.cs b/Library/Providers/SDCard/SDCardContainer.cs index 58867cfe6..f0de1c2d1 100644 --- a/Library/Providers/SDCard/SDCardContainer.cs +++ b/Library/Providers/SDCard/SDCardContainer.cs @@ -30,8 +30,8 @@ either expressed or implied, of the FreeBSD Project. using System; using System.Collections.Generic; using System.Threading.Tasks; +using MatterHackers.Agg; using MatterHackers.Agg.Image; -using MatterHackers.Agg.UI; using MatterHackers.Localizations; using MatterHackers.MatterControl.PrinterCommunication; diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index 34a45bf6b..5abe542b7 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -217,7 +217,7 @@ namespace MatterHackers.MatterControl if (!hasBeenRun && PrinterConnection.Instance.CommunicationState == CommunicationStates.Connected) { hasBeenRun = true; - PrinterConnection.Instance.PrintActivePartIfPossible(); + ApplicationController.Instance.PrintActivePartIfPossible(); } }, ref unregisterEvent); } diff --git a/PartPreviewWindow/ViewGcodeBasic.cs b/PartPreviewWindow/ViewGcodeBasic.cs index 339c40d94..75b29d852 100644 --- a/PartPreviewWindow/ViewGcodeBasic.cs +++ b/PartPreviewWindow/ViewGcodeBasic.cs @@ -54,7 +54,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow private TextWidget gcodeProcessingStateInfoText; private ViewGcodeWidget gcodeViewWidget; - private PrintItemWrapper printItem => PrinterConnection.Instance.ActivePrintItem; + private PrintItemWrapper printItem => ApplicationController.Instance.ActivePrintItem; private bool startedSliceFromGenerateButton = false; private Button generateGCodeButton; private FlowLayoutWidget buttonBottomPanel; @@ -828,7 +828,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow // because the gcode finished creating for the print that is printing. // We don't want to be notified if any other updates happen to this gcode while it is printing. if (PrinterConnection.Instance.PrinterIsPrinting - && PrinterConnection.Instance.ActivePrintItem == printItem) + && ApplicationController.Instance.ActivePrintItem == printItem) { printItem.SlicingOutputMessage -= sliceItem_SlicingOutputMessage; printItem.SlicingDone -= sliceItem_Done; diff --git a/PrinterCommunication/Io/BabyStepsStream.cs b/PrinterCommunication/Io/BabyStepsStream.cs index d794ad026..84a13c29b 100644 --- a/PrinterCommunication/Io/BabyStepsStream.cs +++ b/PrinterCommunication/Io/BabyStepsStream.cs @@ -28,7 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using System; -using MatterHackers.Agg.UI; +using MatterHackers.Agg; using MatterHackers.GCodeVisualizer; using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.VectorMath; diff --git a/PrinterCommunication/Io/PauseHandlingStream.cs b/PrinterCommunication/Io/PauseHandlingStream.cs index f0380fdde..6a566897f 100644 --- a/PrinterCommunication/Io/PauseHandlingStream.cs +++ b/PrinterCommunication/Io/PauseHandlingStream.cs @@ -104,12 +104,12 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io case PauseReason.PauseLayerReached: case PauseReason.GCodeRequest: - pcc.PauseOnLayer.CallEvents(pcc, new PrintItemWrapperEventArgs(pcc.ActivePrintItem)); + pcc.PauseOnLayer.CallEvents(pcc, new PrintItemWrapperEventArgs(pcc.activePrintItem)); UiThread.RunOnIdle(() => StyledMessageBox.ShowMessageBox(ResumePrint, layerPauseMessage.FormatWith(layerNumber), pauseCaption, StyledMessageBox.MessageType.YES_NO, "Ok".Localize(), "Resume".Localize())); break; case PauseReason.FilamentRunout: - pcc.FilamentRunout.CallEvents(pcc, new PrintItemWrapperEventArgs(pcc.ActivePrintItem)); + pcc.FilamentRunout.CallEvents(pcc, new PrintItemWrapperEventArgs(pcc.activePrintItem)); UiThread.RunOnIdle(() => StyledMessageBox.ShowMessageBox(ResumePrint, filamentPauseMessage, pauseCaption, StyledMessageBox.MessageType.YES_NO, "Ok".Localize(), "Resume".Localize())); break; } diff --git a/PrinterCommunication/PrinterConnection.cs b/PrinterCommunication/PrinterConnection.cs index 533b5cd3b..a45de1dcc 100644 --- a/PrinterCommunication/PrinterConnection.cs +++ b/PrinterCommunication/PrinterConnection.cs @@ -31,18 +31,14 @@ using System; using System.Diagnostics; using System.Globalization; using System.IO; -using System.IO.Compression; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Gaming.Game; using MatterHackers.Agg; -using MatterHackers.Agg.UI; using MatterHackers.GCodeVisualizer; using MatterHackers.Localizations; -using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling; -using MatterHackers.MatterControl.CustomWidgets; using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.PrinterCommunication.Io; using MatterHackers.MatterControl.PrintQueue; @@ -105,8 +101,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication /// public class PrinterConnection { - public RootedObjectEventHandler ActivePrintItemChanged = new RootedObjectEventHandler(); - public RootedObjectEventHandler BedTemperatureRead = new RootedObjectEventHandler(); public RootedObjectEventHandler BedTemperatureSet = new RootedObjectEventHandler(); @@ -176,8 +170,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication private readonly int JoinThreadTimeoutMs = 5000; - private PrintItemWrapper activePrintItem; - private PrintTask activePrintTask; private double actualBedTemperature; @@ -204,8 +196,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication private double currentSdBytes = 0; - private string doNotAskAgainMessage = "Don't remind me again".Localize(); - private PrinterMachineInstruction.MovementTypes extruderMode = PrinterMachineInstruction.MovementTypes.Absolute; private int fanSpeed; @@ -216,8 +206,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication private bool ForceImmediateWrites = false; - private string gcodeWarningMessage = "The file you are attempting to print is a GCode file.\n\nIt is recommended that you only print Gcode files known to match your printer's configuration.\n\nAre you sure you want to print this GCode file?".Localize(); - private string itemNotFoundMessage = "Item not found".Localize(); private string lastLineRead = ""; @@ -395,28 +383,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication } } - public PrintItemWrapper ActivePrintItem - { - get - { - return this.activePrintItem; - } - set - { - if (!PrinterIsPrinting - && !PrinterIsPaused - && this.activePrintItem != value) - { - this.activePrintItem = value; - if (CommunicationState == CommunicationStates.FinishedPrint) - { - CommunicationState = CommunicationStates.Connected; - } - OnActivePrintItemChanged(null); - } - } - } - public double ActualBedTemperature { get @@ -1310,7 +1276,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication public void OnPrintFinished(EventArgs e) { - PrintFinished.CallEvents(this, new PrintItemWrapperEventArgs(this.ActivePrintItem)); + PrintFinished.CallEvents(this, new PrintItemWrapperEventArgs(this.activePrintItem)); // TODO: Shouldn't this logic be in the UI layer where the controls are owned and hooked in via PrintFinished? bool oneOrMoreValuesReset = false; @@ -1333,88 +1299,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication } } - public async void PrintActivePart(bool overrideAllowGCode = false) - { - try - { - // If leveling is required or is currently on - if (ActiveSliceSettings.Instance.GetValue(SettingsKey.print_leveling_required_to_print) - || ActiveSliceSettings.Instance.GetValue(SettingsKey.print_leveling_enabled)) - { - PrintLevelingData levelingData = ActiveSliceSettings.Instance.Helpers.GetPrintLevelingData(); - if (levelingData?.HasBeenRunAndEnabled() != true) - { - LevelWizardBase.ShowPrintLevelWizard(); - return; - } - } - - // Save any pending changes before starting the print - await ApplicationController.Instance.ActiveView3DWidget.PersistPlateIfNeeded(); - - if (ActivePrintItem != null) - { - string pathAndFile = ActivePrintItem.FileLocation; - if (ActiveSliceSettings.Instance.GetValue(SettingsKey.has_sd_card_reader) - && pathAndFile == QueueData.SdCardFileName) - { - StartSdCardPrint(); - } - else if (ActiveSliceSettings.Instance.IsValid()) - { - if (File.Exists(pathAndFile)) - { - // clear the output cache prior to starting a print - PrinterOutputCache.Instance.Clear(); - - string hideGCodeWarning = ApplicationSettings.Instance.get(ApplicationSettingsKey.HideGCodeWarning); - - if (Path.GetExtension(pathAndFile).ToUpper() == ".GCODE" - && hideGCodeWarning == null - && !overrideAllowGCode) - { - CheckBox hideGCodeWarningCheckBox = new CheckBox(doNotAskAgainMessage); - hideGCodeWarningCheckBox.TextColor = ActiveTheme.Instance.PrimaryTextColor; - hideGCodeWarningCheckBox.Margin = new BorderDouble(top: 6, left: 6); - hideGCodeWarningCheckBox.HAnchor = Agg.UI.HAnchor.ParentLeft; - hideGCodeWarningCheckBox.Click += (sender, e) => - { - if (hideGCodeWarningCheckBox.Checked) - { - ApplicationSettings.Instance.set(ApplicationSettingsKey.HideGCodeWarning, "true"); - } - else - { - ApplicationSettings.Instance.set(ApplicationSettingsKey.HideGCodeWarning, null); - } - }; - - UiThread.RunOnIdle(() => StyledMessageBox.ShowMessageBox(onConfirmPrint, gcodeWarningMessage, "Warning - GCode file".Localize(), new GuiWidget[] { new VerticalSpacer(), hideGCodeWarningCheckBox }, StyledMessageBox.MessageType.YES_NO)); - } - else - { - CommunicationState = CommunicationStates.PreparingToPrint; - PrintItemWrapper partToPrint = ActivePrintItem; - SlicingQueue.Instance.QueuePartForSlicing(partToPrint); - partToPrint.SlicingDone += partToPrint_SliceDone; - } - } - } - } - } - catch (Exception) - { - } - } - - public void PrintActivePartIfPossible(bool overrideAllowGCode = false) - { - if (CommunicationState == CommunicationStates.Connected || CommunicationState == CommunicationStates.FinishedPrint) - { - PrintActivePart(overrideAllowGCode); - } - } - public void PrinterRequestsResend(object sender, EventArgs e) { FoundStringEventArgs foundStringEventArgs = e as FoundStringEventArgs; @@ -1452,22 +1336,18 @@ namespace MatterHackers.MatterControl.PrinterCommunication private bool haveReportedError = false; + public event EventHandler ErrorReported; + public void PrinterReportsError(object sender, EventArgs e) { if (!haveReportedError) { haveReportedError = true; + FoundStringEventArgs foundStringEventArgs = e as FoundStringEventArgs; if (foundStringEventArgs != null) { - string message = "Your printer is reporting a hardware Error. This may prevent your printer from functioning properly.".Localize() - + "\n" - + "\n" - + "Error Reported".Localize() + ":" - + $" \"{foundStringEventArgs.LineToCheck}\"."; - UiThread.RunOnIdle(() => - StyledMessageBox.ShowMessageBox(null, message, "Printer Hardware Error".Localize()) - ); + ErrorReported?.Invoke(null, foundStringEventArgs); } } } @@ -1656,18 +1536,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication SendLineToPrinterNow(connectGCode); // and call back anyone who would like to know we connected - UiThread.RunOnIdle(() => ConnectionSucceeded.CallEvents(this, null)); - - // run the print leveling wizard if we need to for this printer - if (ActiveSliceSettings.Instance.GetValue(SettingsKey.print_leveling_required_to_print) - || ActiveSliceSettings.Instance.GetValue(SettingsKey.print_leveling_enabled)) - { - PrintLevelingData levelingData = ActiveSliceSettings.Instance.Helpers.GetPrintLevelingData(); - if (levelingData?.HasBeenRunAndEnabled() != true) - { - UiThread.RunOnIdle(LevelWizardBase.ShowPrintLevelWizard); - } - } + ConnectionSucceeded.CallEvents(this, null); } else { @@ -1840,11 +1709,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication CommunicationState = CommunicationStates.Disconnected; // We were connected to a printer so try to reconnect - UiThread.RunOnIdle(() => - { - //HaltConnectionThread(); - ConnectToActivePrinter(); - }, 2); + ConnectToActivePrinter(); } else { @@ -2066,7 +1931,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication { if (!PrinterIsConnected || PrinterIsPrinting - || ActivePrintItem.PrintItem.FileLocation != QueueData.SdCardFileName) + || activePrintItem.PrintItem.FileLocation != QueueData.SdCardFileName) { return false; } @@ -2076,7 +1941,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication ClearQueuedGCode(); CommunicationState = CommunicationStates.PrintingFromSd; - SendLineToPrinterNow("M23 {0}".FormatWith(ActivePrintItem.PrintItem.Name.ToLower())); // Select SD File + SendLineToPrinterNow("M23 {0}".FormatWith(activePrintItem.PrintItem.Name.ToLower())); // Select SD File SendLineToPrinterNow("M24"); // Start/resume SD print ReadLineStartCallBacks.AddCallbackToKey("Done printing file", DonePrintingSdFile); @@ -2328,10 +2193,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication private void DonePrintingSdFile(object sender, FoundStringEventArgs e) { - UiThread.RunOnIdle(() => - { - ReadLineStartCallBacks.RemoveCallbackFromKey("Done printing file", DonePrintingSdFile); - }); + ReadLineStartCallBacks.RemoveCallbackFromKey("Done printing file", DonePrintingSdFile); CommunicationState = CommunicationStates.FinishedPrint; this.PrintJobName = null; @@ -2354,10 +2216,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication private void FileDeleteConfirmed(object sender, EventArgs e) { - UiThread.RunOnIdle(() => - { - ReadLineStartCallBacks.RemoveCallbackFromKey("File deleted:", FileDeleteConfirmed); - }); + ReadLineStartCallBacks.RemoveCallbackFromKey("File deleted:", FileDeleteConfirmed); PrintingCanContinue(this, null); } @@ -2459,6 +2318,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication CreateStreamProcessors(gcodeFilename, ActiveSliceSettings.Instance.GetValue(SettingsKey.recover_is_enabled)); } + internal PrintItemWrapper activePrintItem; + private void DoneLoadingGCodeToPrint() { switch (communicationState) @@ -2468,9 +2329,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication break; case CommunicationStates.PreparingToPrint: - if (ActivePrintItem.PrintItem.Id == 0) + if (activePrintItem.PrintItem.Id == 0) { - ActivePrintItem.PrintItem.Commit(); + activePrintItem.PrintItem.Commit(); } if (activePrintTask == null) @@ -2479,9 +2340,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication activePrintTask = new PrintTask(); activePrintTask.PrintStart = DateTime.Now; activePrintTask.PrinterId = this.ActivePrinter.ID.GetHashCode(); - activePrintTask.PrintName = ActivePrintItem.PrintItem.Name; - activePrintTask.PrintItemId = ActivePrintItem.PrintItem.Id; - activePrintTask.PrintingGCodeFileName = ActivePrintItem.GetGCodePathAndFileName(); + activePrintTask.PrintName = activePrintItem.PrintItem.Name; + activePrintTask.PrintItemId = activePrintItem.PrintItem.Id; + activePrintTask.PrintingGCodeFileName = activePrintItem.GetGCodePathAndFileName(); activePrintTask.PrintComplete = false; activePrintTask.Commit(); @@ -2520,11 +2381,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication OnAtxPowerStateChanged(false); } - private void OnActivePrintItemChanged(EventArgs e) - { - ActivePrintItemChanged.CallEvents(this, e); - } - private void OnBedTemperatureRead(EventArgs e) { BedTemperatureRead.CallEvents(this, e); @@ -2535,17 +2391,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication BedTemperatureSet.CallEvents(this, e); } - private void onConfirmPrint(bool messageBoxResponse) - { - if (messageBoxResponse) - { - CommunicationState = CommunicationStates.PreparingToPrint; - PrintItemWrapper partToPrint = ActivePrintItem; - SlicingQueue.Instance.QueuePartForSlicing(partToPrint); - partToPrint.SlicingDone += partToPrint_SliceDone; - } - } - private void OnEnabledChanged(EventArgs e) { EnableChanged.CallEvents(this, e); @@ -2582,84 +2427,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication AtxPowerStateChanged.CallEvents(this, null); } - private void partToPrint_SliceDone(object sender, EventArgs e) - { - PrintItemWrapper partToPrint = sender as PrintItemWrapper; - if (partToPrint != null) - { - partToPrint.SlicingDone -= partToPrint_SliceDone; - string gcodePathAndFileName = partToPrint.GetGCodePathAndFileName(); - if (gcodePathAndFileName != "") - { - bool originalIsGCode = Path.GetExtension(partToPrint.FileLocation).ToUpper() == ".GCODE"; - if (File.Exists(gcodePathAndFileName)) - { - // Create archive point for printing attempt - if (Path.GetExtension(partToPrint.FileLocation).ToUpper() == ".MCX") - { - // TODO: We should zip mcx and settings when starting a print - string platingDirectory = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, "PrintHistory"); - Directory.CreateDirectory(platingDirectory); - - string now = DateTime.Now.ToString("yyyyMMdd-HHmmss"); - string archivePath = Path.Combine(platingDirectory, now + ".zip"); - - using (var file = File.OpenWrite(archivePath)) - using (var zip = new ZipArchive(file, ZipArchiveMode.Create)) - { - zip.CreateEntryFromFile(partToPrint.FileLocation, "PrinterPlate.mcx"); - zip.CreateEntryFromFile(ActiveSliceSettings.Instance.DocumentPath, ActiveSliceSettings.Instance.GetValue(SettingsKey.printer_name) + ".printer"); - zip.CreateEntryFromFile(gcodePathAndFileName, "sliced.gcode"); - } - } - - // read the last few k of the file and see if it says "filament used". We use this marker to tell if the file finished writing - if (originalIsGCode) - { - StartPrint(gcodePathAndFileName); - return; - } - else - { - int bufferSize = 32000; - using (Stream fileStream = new FileStream(gcodePathAndFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - { - byte[] buffer = new byte[bufferSize]; - fileStream.Seek(Math.Max(0, fileStream.Length - bufferSize), SeekOrigin.Begin); - int numBytesRead = fileStream.Read(buffer, 0, bufferSize); - fileStream.Close(); - - string fileEnd = System.Text.Encoding.UTF8.GetString(buffer); - if (fileEnd.Contains("filament used")) - { - if (firmwareUriGcodeSend) - { - currentSdBytes = 0; - - ClearQueuedGCode(); - - SendLineToPrinterNow("M23 {0}".FormatWith(gcodePathAndFileName)); // Send the SD File - SendLineToPrinterNow("M24"); // Start/resume SD print - - CommunicationState = CommunicationStates.PrintingFromSd; - - ReadLineStartCallBacks.AddCallbackToKey("Done printing file", DonePrintingSdFile); - } - else - { - StartPrint(gcodePathAndFileName); - } - return; - } - } - } - } - - CommunicationState = CommunicationStates.Connected; - } - } - } - private void SetDetailedPrintingState(string lineBeingSetToPrinter) { if (lineBeingSetToPrinter.StartsWith("G28")) diff --git a/Queue/OptionsMenu/ExportToFolderProcess.cs b/Queue/OptionsMenu/ExportToFolderProcess.cs index a5673065d..84fc8c535 100644 --- a/Queue/OptionsMenu/ExportToFolderProcess.cs +++ b/Queue/OptionsMenu/ExportToFolderProcess.cs @@ -27,17 +27,16 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ -using MatterHackers.Agg.UI; +using System; +using System.Collections.Generic; +using System.IO; +using MatterHackers.Agg; using MatterHackers.DataConverters3D; using MatterHackers.GCodeVisualizer; using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling; using MatterHackers.MatterControl.DataStorage; using MatterHackers.MatterControl.SlicerConfiguration; -using MatterHackers.PolygonMesh.Processors; using MatterHackers.VectorMath; -using System; -using System.Collections.Generic; -using System.IO; namespace MatterHackers.MatterControl.PrintQueue { diff --git a/Queue/QueueData.cs b/Queue/QueueData.cs index 1dc7f0f0f..09864bab4 100644 --- a/Queue/QueueData.cs +++ b/Queue/QueueData.cs @@ -85,7 +85,7 @@ namespace MatterHackers.MatterControl.PrintQueue if (index >= 0 && index < ItemCount) { bool ActiveItemMustStayInQueue = PrinterConnection.Instance.PrinterIsPrinting || PrinterConnection.Instance.PrinterIsPaused; - bool PartMustStayInQueue = ActiveItemMustStayInQueue && PrintItems[index] == PrinterConnection.Instance.ActivePrintItem; + bool PartMustStayInQueue = ActiveItemMustStayInQueue && PrintItems[index] == ApplicationController.Instance.ActivePrintItem; if (!PartMustStayInQueue) { PrintItems.RemoveAt(index); diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 12da29407..97aa01e04 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 12da2940771e1c9480fe8a75ea9768ebf2ef6f2c +Subproject commit 97aa01e04e3130a61a886bcd662e37397ebef546 diff --git a/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs b/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs index 014cc1f6d..f496b01fb 100644 --- a/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs +++ b/Tests/MatterControl.AutomationTests/SliceSettingsTests.cs @@ -1,12 +1,9 @@ using System; -using System.Diagnostics; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MatterHackers.Agg.PlatformAbstract; +using MatterHackers.Agg; using MatterHackers.Agg.UI; -using MatterHackers.Agg.UI.Tests; using MatterHackers.GuiAutomation; using MatterHackers.MatterControl.SlicerConfiguration; using NUnit.Framework;