/// <summary>
        /// Validates printer satisfies all requirements
        /// </summary>
        /// <param name="printer">The printer to validate</param>
        /// <returns>A list of all warnings and errors</returns>
        public static List <ValidationError> Validate(this PrinterConfig printer)
        {
            var errors = new List <ValidationError>();

            var printerIsConnected = printer.Connection.CommunicationState != PrinterCommunication.CommunicationStates.Disconnected;

            if (!printerIsConnected)
            {
                errors.Add(new ValidationError("PrinterDisconnected")
                {
                    Error     = "Printer Disconnected".Localize(),
                    Details   = "Connect to your printer to continue".Localize(),
                    FixAction = new NamedAction()
                    {
                        Title  = "Connect".Localize(),
                        Action = () =>
                        {
                            // TODO: Extract the behavior in the Connect/Disconnect button from widget land so we can reuse a common implementation
                            printer.Connection.HaltConnectionThread();
                            printer.Connection.Connect();
                        }
                    }
                });
            }

            // TODO: Consider splitting out each individual requirement in PrinterNeedsToRunSetup and reporting validation in a more granular fashion
            if (ApplicationController.PrinterNeedsToRunSetup(printer))
            {
                errors.Add(new ValidationError("PrinterSetupRequired")
                {
                    Error     = "Printer Setup Required".Localize(),
                    Details   = "Printer Setup must be run before printing".Localize(),
                    FixAction = new NamedAction()
                    {
                        ID     = "SetupPrinter",
                        Title  = "Setup".Localize() + "...",
                        Action = () =>
                        {
                            UiThread.RunOnIdle(async() =>
                            {
                                await ApplicationController.Instance.PrintPart(
                                    printer.Bed.EditContext,
                                    printer,
                                    null,
                                    CancellationToken.None);
                            });
                        }
                    }
                });
            }

            // Concat printer and settings errors
            errors.AddRange(printer.ValidateSettings());

            return(errors);
        }
        /// <summary>
        /// Validates printer satisfies all requirements.
        /// </summary>
        /// <param name="printer">The printer to validate.</param>
        /// <returns>A list of all warnings and errors.</returns>
        public static List <ValidationError> Validate(this PrinterConfig printer)
        {
            var errors = new List <ValidationError>();

            var fffPrinter = printer.Settings.Slicer.PrinterType == PrinterType.FFF;

            if (!printer.Connection.IsConnected &&
                fffPrinter)
            {
                errors.Add(new ValidationError(ValidationErrors.PrinterDisconnected)
                {
                    Error     = "Printer Disconnected".Localize(),
                    Details   = "Connect to your printer to continue".Localize(),
                    FixAction = new NamedAction()
                    {
                        Title  = "Connect".Localize(),
                        Action = () => ApplicationController.Instance.ConnectToPrinter(printer)
                    }
                });
            }

            if (PrinterSetupRequired(printer))
            {
                errors.Add(new ValidationError(ValidationErrors.PrinterSetupRequired)
                {
                    Error     = "Printer Setup Required".Localize(),
                    Details   = "Printer Setup must be run before printing".Localize(),
                    FixAction = new NamedAction()
                    {
                        ID     = "SetupPrinter",
                        Title  = "Setup".Localize() + "...",
                        Action = () =>
                        {
                            UiThread.RunOnIdle(() =>
                            {
                                DialogWindow.Show(
                                    new PrinterCalibrationWizard(printer, AppContext.Theme),
                                    advanceToIncompleteStage: true);
                            });
                        }
                    }
                });
            }

            // Concatenate printer and settings errors
            errors.AddRange(printer.ValidateSettings(validatePrintBed: !printer.Bed.EditContext.IsGGCodeSource));

            return(errors);
        }
Esempio n. 3
0
        public ExportPrintItemPage(IEnumerable <ILibraryItem> libraryItems, bool centerOnBed, PrinterConfig printer)
        {
            this.WindowTitle = "Export File".Localize();
            this.HeaderText  = "Export selection to".Localize() + ":";
            this.Name        = "Export Item Window";

            var commonMargin = new BorderDouble(4, 2);

            bool isFirstItem = true;

            // Must be constructed before plugins are initialized
            var exportButton = theme.CreateDialogButton("Export".Localize());

            validationPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit
            };

            // GCode export
            exportPluginButtons = new Dictionary <RadioButton, IExportPlugin>();

            foreach (IExportPlugin plugin in PluginFinder.CreateInstancesOf <IExportPlugin>().OrderBy(p => p.ButtonText))
            {
                plugin.Initialize(printer);

                // Skip plugins which are invalid for the current printer
                if (!plugin.Enabled)
                {
                    if (!string.IsNullOrEmpty(plugin.DisabledReason))
                    {
                        // add a message to let us know why not enabled
                        var disabledPluginButton = new RadioButton(new RadioImageWidget(plugin.ButtonText, theme.TextColor, plugin.Icon))
                        {
                            HAnchor = HAnchor.Left,
                            Margin  = commonMargin,
                            Cursor  = Cursors.Hand,
                            Name    = plugin.ButtonText + " Button",
                            Enabled = false
                        };
                        contentRow.AddChild(disabledPluginButton);
                        contentRow.AddChild(new TextWidget("Disabled: {0}".Localize().FormatWith(plugin.DisabledReason), textColor: theme.PrimaryAccentColor)
                        {
                            Margin  = new BorderDouble(left: 80),
                            HAnchor = HAnchor.Left
                        });
                    }
                    continue;
                }

                // Create export button for each plugin
                var pluginButton = new RadioButton(new RadioImageWidget(plugin.ButtonText, theme.TextColor, plugin.Icon))
                {
                    HAnchor = HAnchor.Left,
                    Margin  = commonMargin,
                    Cursor  = Cursors.Hand,
                    Name    = plugin.ButtonText + " Button"
                };
                contentRow.AddChild(pluginButton);

                if (plugin is GCodeExport)
                {
                    var gcodeExportButton = pluginButton;
                    gcodeExportButton.CheckedStateChanged += (s, e) =>
                    {
                        validationPanel.CloseAllChildren();

                        if (gcodeExportButton.Checked)
                        {
                            var errors = printer.ValidateSettings(validatePrintBed: false);

                            exportButton.Enabled = !errors.Any(item => item.ErrorLevel == ValidationErrorLevel.Error);

                            validationPanel.AddChild(
                                new ValidationErrorsPanel(
                                    errors,
                                    AppContext.Theme)
                            {
                                HAnchor = HAnchor.Stretch
                            });
                        }
                        else
                        {
                            exportButton.Enabled = true;
                        }
                    };
                }

                if (isFirstItem)
                {
                    pluginButton.Checked = true;
                    isFirstItem          = false;
                }

                if (plugin is IExportWithOptions pluginWithOptions)
                {
                    var optionPanel = pluginWithOptions.GetOptionsPanel();
                    if (optionPanel != null)
                    {
                        optionPanel.HAnchor = HAnchor.Stretch;
                        optionPanel.VAnchor = VAnchor.Fit;
                        contentRow.AddChild(optionPanel);
                    }
                }

                exportPluginButtons.Add(pluginButton, plugin);
            }

            ContentRow.AddChild(new VerticalSpacer());
            contentRow.AddChild(validationPanel);

            // TODO: make this work on the mac and then delete this if
            if (AggContext.OperatingSystem == OSType.Windows ||
                AggContext.OperatingSystem == OSType.X11)
            {
                showInFolderAfterSave = new CheckBox("Show file in folder after save".Localize(), theme.TextColor, 10)
                {
                    HAnchor = HAnchor.Left,
                    Cursor  = Cursors.Hand
                };
                contentRow.AddChild(showInFolderAfterSave);
            }

            exportButton.Name   = "Export Button";
            exportButton.Click += (s, e) =>
            {
                IExportPlugin activePlugin = null;

                // Loop over all plugin buttons, break on the first checked item found
                foreach (var button in this.exportPluginButtons.Keys)
                {
                    if (button.Checked)
                    {
                        activePlugin = exportPluginButtons[button];
                        break;
                    }
                }

                // Early exit if no plugin radio button is selected
                if (activePlugin == null)
                {
                    return;
                }

                DoExport(libraryItems, printer, activePlugin, centerOnBed, showInFolderAfterSave.Checked);

                this.Parent.CloseOnIdle();
            };


            this.AddPageAction(exportButton);
        }
Esempio n. 4
0
        public ExportPrintItemPage(IEnumerable <ILibraryItem> libraryItems, bool centerOnBed, PrinterConfig printer)
        {
            this.centerOnBed = centerOnBed;
            this.WindowTitle = "Export File".Localize();
            this.HeaderText  = "Export selection to".Localize() + ":";

            this.libraryItems = libraryItems;
            this.Name         = "Export Item Window";

            var commonMargin = new BorderDouble(4, 2);

            bool isFirstItem = true;

            // Must be constructed before plugins are initialized
            var exportButton = theme.CreateDialogButton("Export".Localize());

            validationPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit
            };

            // GCode export
            exportPluginButtons = new Dictionary <RadioButton, IExportPlugin>();

            foreach (IExportPlugin plugin in PluginFinder.CreateInstancesOf <IExportPlugin>().OrderBy(p => p.ButtonText))
            {
                plugin.Initialize(printer);

                // Skip plugins which are invalid for the current printer
                if (!plugin.Enabled)
                {
                    if (!string.IsNullOrEmpty(plugin.DisabledReason))
                    {
                        // add a message to let us know why not enabled
                        var disabledPluginButton = new RadioButton(new RadioImageWidget(plugin.ButtonText, theme.TextColor, plugin.Icon))
                        {
                            HAnchor = HAnchor.Left,
                            Margin  = commonMargin,
                            Cursor  = Cursors.Hand,
                            Name    = plugin.ButtonText + " Button",
                            Enabled = false
                        };
                        contentRow.AddChild(disabledPluginButton);
                        contentRow.AddChild(new TextWidget("Disabled: {0}".Localize().FormatWith(plugin.DisabledReason), textColor: theme.PrimaryAccentColor)
                        {
                            Margin  = new BorderDouble(left: 80),
                            HAnchor = HAnchor.Left
                        });
                    }
                    continue;
                }

                // Create export button for each plugin
                var pluginButton = new RadioButton(new RadioImageWidget(plugin.ButtonText, theme.TextColor, plugin.Icon))
                {
                    HAnchor = HAnchor.Left,
                    Margin  = commonMargin,
                    Cursor  = Cursors.Hand,
                    Name    = plugin.ButtonText + " Button"
                };
                contentRow.AddChild(pluginButton);

                if (plugin is GCodeExport)
                {
                    var gcodeExportButton = pluginButton;
                    gcodeExportButton.CheckedStateChanged += (s, e) =>
                    {
                        validationPanel.CloseAllChildren();

                        if (gcodeExportButton.Checked)
                        {
                            var errors = printer.ValidateSettings();

                            exportButton.Enabled = !errors.Any(item => item.ErrorLevel == ValidationErrorLevel.Error);

                            validationPanel.AddChild(
                                new ValidationErrorsPanel(
                                    errors,
                                    AppContext.Theme)
                            {
                                HAnchor = HAnchor.Stretch
                            });
                        }
                        else
                        {
                            exportButton.Enabled = true;
                        }
                    };
                }

                if (isFirstItem)
                {
                    pluginButton.Checked = true;
                    isFirstItem          = false;
                }

                if (plugin is IExportWithOptions pluginWithOptions)
                {
                    var optionPanel = pluginWithOptions.GetOptionsPanel();
                    if (optionPanel != null)
                    {
                        optionPanel.HAnchor = HAnchor.Stretch;
                        optionPanel.VAnchor = VAnchor.Fit;
                        contentRow.AddChild(optionPanel);
                    }
                }


                exportPluginButtons.Add(pluginButton, plugin);
            }

            ContentRow.AddChild(new VerticalSpacer());
            contentRow.AddChild(validationPanel);

            // TODO: make this work on the mac and then delete this if
            if (AggContext.OperatingSystem == OSType.Windows ||
                AggContext.OperatingSystem == OSType.X11)
            {
                showInFolderAfterSave = new CheckBox("Show file in folder after save".Localize(), theme.TextColor, 10)
                {
                    HAnchor = HAnchor.Left,
                    Cursor  = Cursors.Hand
                };
                contentRow.AddChild(showInFolderAfterSave);
            }

            exportButton.Name   = "Export Button";
            exportButton.Click += (s, e) =>
            {
                string fileTypeFilter  = "";
                string targetExtension = "";

                IExportPlugin activePlugin = null;

                // Loop over all plugin buttons, break on the first checked item found
                foreach (var button in this.exportPluginButtons.Keys)
                {
                    if (button.Checked)
                    {
                        activePlugin = exportPluginButtons[button];
                        break;
                    }
                }

                // Early exit if no plugin radio button is selected
                if (activePlugin == null)
                {
                    return;
                }

                fileTypeFilter  = activePlugin.ExtensionFilter;
                targetExtension = activePlugin.FileExtension;

                this.Parent.CloseOnIdle();

                if (activePlugin is FolderExport)
                {
                    UiThread.RunOnIdle(() =>
                    {
                        AggContext.FileDialogs.SelectFolderDialog(
                            new SelectFolderDialogParams("Select Location To Export Files")
                        {
                            ActionButtonLabel = "Export".Localize(),
                            Title             = ApplicationController.Instance.ProductName + " - " + "Select A Folder".Localize()
                        },
                            (openParams) =>
                        {
                            ApplicationController.Instance.Tasks.Execute(
                                "Saving".Localize() + "...",
                                printer,
                                async(reporter, cancellationToken) =>
                            {
                                string path = openParams.FolderPath;
                                if (!string.IsNullOrEmpty(path))
                                {
                                    await activePlugin.Generate(libraryItems, path, reporter, cancellationToken);
                                }
                            });
                        });
                    });

                    return;
                }

                UiThread.RunOnIdle(() =>
                {
                    string title         = ApplicationController.Instance.ProductName + " - " + "Export File".Localize();
                    string workspaceName = "Workspace " + DateTime.Now.ToString("yyyy-MM-dd HH_mm_ss");
                    AggContext.FileDialogs.SaveFileDialog(
                        new SaveFileDialogParams(fileTypeFilter)
                    {
                        Title             = title,
                        ActionButtonLabel = "Export".Localize(),
                        FileName          = Path.GetFileNameWithoutExtension(libraryItems.FirstOrDefault()?.Name ?? workspaceName)
                    },
                        (saveParams) =>
                    {
                        string savePath = saveParams.FileName;

                        if (!string.IsNullOrEmpty(savePath))
                        {
                            ApplicationController.Instance.Tasks.Execute(
                                "Exporting".Localize() + "...",
                                printer,
                                async(reporter, cancellationToken) =>
                            {
                                string extension = Path.GetExtension(savePath);
                                if (extension != targetExtension)
                                {
                                    savePath += targetExtension;
                                }

                                List <ValidationError> exportErrors = null;

                                if (activePlugin != null)
                                {
                                    if (activePlugin is GCodeExport gCodeExport)
                                    {
                                        gCodeExport.CenterOnBed = centerOnBed;
                                    }

                                    exportErrors = await activePlugin.Generate(libraryItems, savePath, reporter, cancellationToken);
                                }

                                if (exportErrors == null || exportErrors.Count == 0)
                                {
                                    ShowFileIfRequested(savePath);
                                }
                                else
                                {
                                    bool showGenerateErrors = !(activePlugin is GCodeExport);

                                    // Only show errors in Generate if not GCodeExport - GCodeExport shows validation errors before Generate call
                                    if (showGenerateErrors)
                                    {
                                        ApplicationController.Instance.ShowValidationErrors("Export Error".Localize(), exportErrors);
                                    }
                                }
                            });
                        }
                    });
                });
            };

            this.AddPageAction(exportButton);
        }