Reduce presentation data in validation errors

- Add ValidationError type to hold validation results
- Change validation to return lists of ValidationErrors
This commit is contained in:
John Lewin 2019-01-04 17:09:42 -08:00
parent 83fcf4f128
commit 063db01796
12 changed files with 265 additions and 76 deletions

View file

@ -2254,7 +2254,12 @@ namespace MatterHackers.MatterControl
var errors = SettingsValidation.SettingsValid(printer);
if(errors.Count > 0)
{
StyledMessageBox.ShowMessageBox(String.Join("\n__________________\n\n", errors.ToArray()), "Slice Error".Localize());
// Project to newline separated Error/Details string
var formattedErrors = errors.Select(err => $"{err.Error}\n\n{err.Details}").ToArray();
StyledMessageBox.ShowMessageBox(
string.Join("\n__________________\n\n", formattedErrors),
"Export Error".Localize());
}
else // there are no erros continue printing
{

View file

@ -37,11 +37,11 @@ namespace MatterHackers.MatterControl
{
public static class SettingsValidation
{
public static List<string> SettingsValid(PrinterConfig printer)
public static List<ValidationError> SettingsValid(PrinterConfig printer)
{
var settings = printer.Settings;
var errors = new List<string>();
var errors = new List<ValidationError>();
try
{
@ -49,34 +49,46 @@ namespace MatterHackers.MatterControl
{
if (settings.GetValue<double>(SettingsKey.layer_height) > settings.GetValue<double>(SettingsKey.nozzle_diameter))
{
var error = "{0} must be less than or equal to the {1}.".Localize().FormatWith(
GetSettingsName(SettingsKey.layer_height), GetSettingsName(SettingsKey.nozzle_diameter));
var details = "{0} = {1}\n{2} = {3}".FormatWith(GetSettingsName(SettingsKey.layer_height),
settings.GetValue<double>(SettingsKey.layer_height),
GetSettingsName(SettingsKey.nozzle_diameter),
settings.GetValue<double>(SettingsKey.nozzle_diameter));
var location = GetSettingsLocation(SettingsKey.layer_height);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "{0} must be less than or equal to the {1}.".Localize().FormatWith(
GetSettingsName(SettingsKey.layer_height), GetSettingsName(SettingsKey.nozzle_diameter)),
Details = $"{details}\n\n{GetSettingsLocation(SettingsKey.layer_height)}"
});
}
else if (settings.GetValue<double>(SettingsKey.layer_height) <= 0)
{
var error = "{0} must be greater than 0.".Localize().FormatWith(
GetSettingsName(SettingsKey.layer_height));
var location = GetSettingsLocation(SettingsKey.layer_height);
errors.Add($"{error}\n\n{location}");
errors.Add(
new ValidationError()
{
Error = "{0} must be greater than 0.".Localize().FormatWith(GetSettingsName(SettingsKey.layer_height)),
Details = GetSettingsLocation(SettingsKey.layer_height)
});
}
else if (settings.GetValue<double>(SettingsKey.first_layer_height) > settings.GetValue<double>(SettingsKey.nozzle_diameter))
{
var error = "{0} must be less than or equal to the {1}.".Localize().FormatWith(
GetSettingsName(SettingsKey.layer_height),
GetSettingsName(SettingsKey.nozzle_diameter));
var details = "{0} = {1}\n{2} = {3}".FormatWith(
GetSettingsName(SettingsKey.first_layer_height),
settings.GetValue<double>(SettingsKey.first_layer_height),
GetSettingsName(SettingsKey.nozzle_diameter),
settings.GetValue<double>(SettingsKey.nozzle_diameter));
var location = GetSettingsLocation(SettingsKey.first_layer_height);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "{0} must be less than or equal to the {1}.".Localize().FormatWith(
GetSettingsName(SettingsKey.layer_height),
GetSettingsName(SettingsKey.nozzle_diameter)),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
}
@ -87,20 +99,30 @@ namespace MatterHackers.MatterControl
{
foreach (string startGCodeLine in startGCode)
{
var location = GetSettingsLocation(SettingsKey.start_gcode);
if (startGCodeLine.StartsWith("G29"))
{
var location = GetSettingsLocation(SettingsKey.start_gcode);
var error = "Start G-Code cannot contain G29 if Print Recovery is enabled.".Localize();
var details = "Your Start G-Code should not contain a G29 if you are planning on using Print Recovery. Change your start G-Code or turn off Print Recovery.".Localize();
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "Start G-Code cannot contain G29 if Print Recovery is enabled.".Localize(),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
if (startGCodeLine.StartsWith("G30"))
{
var location = GetSettingsLocation(SettingsKey.start_gcode);
var error = "Start G-Code cannot contain G30 if Print Leveling is enabled.".Localize();
var details = "Your Start G-Code should not contain a G30 if you are planning on using Print Recovery. Change your start G-Code or turn off Print Recovery.".Localize();
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "Start G-Code cannot contain G30 if Print Leveling is enabled.".Localize(),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
}
}
@ -113,17 +135,27 @@ namespace MatterHackers.MatterControl
if (startGCodeLine.StartsWith("G29"))
{
var location = GetSettingsLocation(SettingsKey.start_gcode);
var error = "Start G-Code cannot contain G29 if Print Leveling is enabled.".Localize();
var details = "Your Start G-Code should not contain a G29 if you are planning on using print leveling. Change your start G-Code or turn off print leveling.".Localize();
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "Start G-Code cannot contain G29 if Print Leveling is enabled.".Localize(),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
if (startGCodeLine.StartsWith("G30"))
{
var location = GetSettingsLocation(SettingsKey.start_gcode);
var error = "Start G-Code cannot contain G30 if Print Leveling is enabled.".Localize();
var details = "Your Start G-Code should not contain a G30 if you are planning on using print leveling. Change your start G-Code or turn off print leveling.".Localize();
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "Start G-Code cannot contain G30 if Print Leveling is enabled.".Localize(),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
}
}
@ -135,89 +167,133 @@ namespace MatterHackers.MatterControl
location += "\n" + "Controls".Localize();
location += "\n • " + "Movement".Localize();
location += "\n • " + "Z Offset".Localize();
var error = "Z Offset is too large.".Localize();
var details = "The Z Offset for your printer, sometimes called Baby Stepping, is greater than 2mm and invalid. Clear the value and re-level the bed.".Localize();
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "Z Offset is too large.".Localize(),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
if (settings.GetValue<double>(SettingsKey.first_layer_extrusion_width) > settings.GetValue<double>(SettingsKey.nozzle_diameter) * 4)
{
var error = "{0} must be less than or equal to the {1} * 4.".Localize().FormatWith(
GetSettingsName(SettingsKey.first_layer_extrusion_width),
GetSettingsName(SettingsKey.nozzle_diameter));
var details = "{0} = {1}\n{2} = {3}".FormatWith(
GetSettingsName(SettingsKey.first_layer_extrusion_width),
settings.GetValue<double>(SettingsKey.first_layer_extrusion_width),
GetSettingsName(SettingsKey.nozzle_diameter),
settings.GetValue<double>(SettingsKey.nozzle_diameter));
string location = GetSettingsLocation(SettingsKey.first_layer_extrusion_width);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "{0} must be less than or equal to the {1} * 4.".Localize().FormatWith(
GetSettingsName(SettingsKey.first_layer_extrusion_width),
GetSettingsName(SettingsKey.nozzle_diameter)),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
if (settings.GetValue<double>(SettingsKey.first_layer_extrusion_width) <= 0)
{
var error = "{0} must be greater than 0.".Localize().FormatWith(
GetSettingsName(SettingsKey.first_layer_extrusion_width));
var details = "{0} = {1}".FormatWith(
GetSettingsName(SettingsKey.first_layer_extrusion_width),
settings.GetValue<double>(SettingsKey.first_layer_extrusion_width));
string location = GetSettingsLocation(SettingsKey.first_layer_extrusion_width);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "{0} must be greater than 0.".Localize().FormatWith(
GetSettingsName(SettingsKey.first_layer_extrusion_width)),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
if (settings.GetValue<double>(SettingsKey.external_perimeter_extrusion_width) > settings.GetValue<double>(SettingsKey.nozzle_diameter) * 4)
{
var error = "{0} must be less than or equal to the {1} * 4.".Localize().FormatWith(
GetSettingsName(SettingsKey.external_perimeter_extrusion_width),
GetSettingsName(SettingsKey.nozzle_diameter));
var details = "{0} = {1}\n{2} = {3}".FormatWith(
GetSettingsName(SettingsKey.external_perimeter_extrusion_width),
settings.GetValue<double>(SettingsKey.external_perimeter_extrusion_width),
GetSettingsName(SettingsKey.nozzle_diameter),
settings.GetValue<double>(SettingsKey.nozzle_diameter));
string location = GetSettingsLocation(SettingsKey.external_perimeter_extrusion_width);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "{0} must be less than or equal to the {1} * 4.".Localize().FormatWith(
GetSettingsName(SettingsKey.external_perimeter_extrusion_width),
GetSettingsName(SettingsKey.nozzle_diameter)),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
if (settings.GetValue<double>(SettingsKey.external_perimeter_extrusion_width) <= 0)
{
var error = "{0} must be greater than 0.".Localize().FormatWith(
GetSettingsName(SettingsKey.external_perimeter_extrusion_width));
var details = "{0} = {1}".FormatWith(
GetSettingsName(SettingsKey.external_perimeter_extrusion_width),
settings.GetValue<double>(SettingsKey.external_perimeter_extrusion_width));
var location = GetSettingsLocation(SettingsKey.external_perimeter_extrusion_width);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "{0} must be greater than 0.".Localize().FormatWith(
GetSettingsName(SettingsKey.external_perimeter_extrusion_width)),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
if (settings.GetValue<double>(SettingsKey.min_fan_speed) > 100)
{
var error = "The {0} can only go as high as 100%.".Localize().FormatWith(
GetSettingsName(SettingsKey.min_fan_speed));
var details = "It is currently set to {0}.".Localize().FormatWith(
settings.GetValue<double>(SettingsKey.min_fan_speed));
var location = GetSettingsLocation(SettingsKey.min_fan_speed);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "The {0} can only go as high as 100%.".Localize().FormatWith(
GetSettingsName(SettingsKey.min_fan_speed)),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
if (settings.GetValue<double>(SettingsKey.max_fan_speed) > 100)
{
var error = "The {0} can only go as high as 100%.".Localize().FormatWith(
GetSettingsName(SettingsKey.max_fan_speed));
var details = "It is currently set to {0}.".Localize().FormatWith(
settings.GetValue<double>(SettingsKey.max_fan_speed));
var location = GetSettingsLocation(SettingsKey.max_fan_speed);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "The {0} can only go as high as 100%.".Localize().FormatWith(
GetSettingsName(SettingsKey.max_fan_speed)),
Details = "{0}\n\n{1".FormatWith(details, location)
});
}
if (settings.GetValue<int>(SettingsKey.extruder_count) < 1)
{
var error = "The {0} must be at least 1.".Localize().FormatWith(
GetSettingsName(SettingsKey.extruder_count));
var details = "It is currently set to {0}.".Localize().FormatWith(
settings.GetValue<int>(SettingsKey.extruder_count));
var location = GetSettingsLocation(SettingsKey.extruder_count);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "The {0} must be at least 1.".Localize().FormatWith(
GetSettingsName(SettingsKey.extruder_count)),
Details= "{0}\n\n{1}".FormatWith(details, location)
});
}
if (settings.GetValue<double>(SettingsKey.fill_density) < 0 || settings.GetValue<double>(SettingsKey.fill_density) > 1)
@ -227,7 +303,14 @@ namespace MatterHackers.MatterControl
var details = "It is currently set to {0}.".Localize().FormatWith(
settings.GetValue<double>(SettingsKey.fill_density));
var location = GetSettingsLocation(SettingsKey.filament_density);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = error,
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
// marlin firmware can only take a max of 128 bytes in a single instrection, make sure no lines are longer than that
@ -256,8 +339,12 @@ namespace MatterHackers.MatterControl
}
catch (Exception e)
{
errors.Add(e.Message);
errors.Add(e.StackTrace.Replace("\r", ""));
errors.Add(
new ValidationError()
{
Error = "Unexpected error validating settings".Localize(),
Details = e.Message
});
}
return errors;
@ -291,7 +378,7 @@ namespace MatterHackers.MatterControl
return settingData.PresentationName.Localize();
}
private static bool ValidateGCodeLinesShortEnough(string gCodeSetting, PrinterConfig printer, List<string> errors)
private static bool ValidateGCodeLinesShortEnough(string gCodeSetting, PrinterConfig printer, List<ValidationError> errors)
{
string[] gCodeString = printer.Settings.GetValue(SettingsKey.start_gcode).Replace("\\n", "\n").Split('\n');
@ -307,10 +394,15 @@ namespace MatterHackers.MatterControl
{
var location = GetSettingsLocation(gCodeSetting);
var error = "All G-Code lines mush be shorter than 100 characters (excluding comments).".Localize().FormatWith(data.PresentationName);
var details = "Found a line that is {0} characters long.\n{1}...".Localize().FormatWith(length, trimedLine.Substring(0, 20));
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "All G-Code lines mush be shorter than 100 characters (excluding comments).".Localize().FormatWith(data.PresentationName),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
return false;
}
}
@ -318,7 +410,7 @@ namespace MatterHackers.MatterControl
return true;
}
private static void ValidateGoodSpeedSettingGreaterThan0(string speedSetting, PrinterConfig printer, List<string> errors)
private static void ValidateGoodSpeedSettingGreaterThan0(string speedSetting, PrinterConfig printer, List<ValidationError> errors)
{
var actualSpeedValueString = printer.Settings.GetValue(speedSetting);
var speedValueString = actualSpeedValueString;
@ -326,9 +418,10 @@ namespace MatterHackers.MatterControl
{
speedValueString = speedValueString.Substring(0, speedValueString.Length - 1);
}
bool valueWasNumber = true;
double speedToCheck;
if (!double.TryParse(speedValueString, out speedToCheck))
if (!double.TryParse(speedValueString, out double speedToCheck))
{
valueWasNumber = false;
}
@ -342,9 +435,14 @@ namespace MatterHackers.MatterControl
{
var location = GetSettingsLocation(speedSetting);
var error = "The {0} must be greater than 0.".Localize().FormatWith(data.PresentationName);
var details = "It is currently set to {0}.".Localize().FormatWith(actualSpeedValueString);
errors.Add("{0}\n\n{1}\n\n{2}".FormatWith(error, details, location));
errors.Add(
new ValidationError()
{
Error = "The {0} must be greater than 0.".Localize().FormatWith(data.PresentationName),
Details = "{0}\n\n{1}".FormatWith(details, location)
});
}
}
}

View file

@ -0,0 +1,42 @@
/*
Copyright (c) 2019, 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.
*/
namespace MatterHackers.MatterControl
{
public class ValidationError
{
public string Error { get; set; }
public string Details { get; set; }
public string Source { get; set; }
public string SourceName { get; set; }
}
}

View file

@ -226,7 +226,7 @@ namespace MatterHackers.MatterControl
savePath += targetExtension;
}
List<string> exportErrors = null;
List<ValidationError> exportErrors = null;
if (activePlugin != null)
{
@ -245,7 +245,12 @@ namespace MatterHackers.MatterControl
{
UiThread.RunOnIdle(() =>
{
StyledMessageBox.ShowMessageBox(String.Join("\n__________________\n\n", exportErrors.ToArray()), "Export Error".Localize());
// Project to newline separated Error/Details string
var formattedErrors = exportErrors.Select(err => $"{err.Error}\n\n{err.Details}").ToArray();
StyledMessageBox.ShowMessageBox(
string.Join("\n__________________\n\n", formattedErrors),
"Export Error".Localize());
});
}
});

View file

@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.Library.Export
public bool ExportPossible(ILibraryAsset libraryItem) => true;
public async Task<List<string>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
public async Task<List<ValidationError>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
{
var streamItems = libraryItems.OfType<ILibraryAssetStream>();
if (streamItems.Any())
@ -92,7 +92,13 @@ namespace MatterHackers.MatterControl.Library.Export
return null;
}
return new List<string>() { "No items to Export".Localize() };
return new List<ValidationError>()
{
new ValidationError()
{
Error = "No items to Export".Localize()
}
};
}
}
}

View file

@ -136,7 +136,7 @@ namespace MatterHackers.MatterControl.Library.Export
return container;
}
public virtual async Task<List<string>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
public virtual async Task<List<ValidationError>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
{
var firstItem = libraryItems.OfType<ILibraryAsset>().FirstOrDefault();
if (firstItem != null)
@ -264,7 +264,14 @@ namespace MatterHackers.MatterControl.Library.Export
}
}
return new List<string>() { "Item cannot be exported".Localize() + " " + firstItem != null ? firstItem.ToString() : "" };
return new List<ValidationError>
{
new ValidationError()
{
Error = "Item cannot be exported".Localize(),
Details = firstItem?.ToString() ?? ""
}
};
}
public bool ApplyLeveling { get; set; } = true;

View file

@ -46,7 +46,7 @@ namespace MatterHackers.MatterControl
void Initialize(PrinterConfig printer);
Task<List<string>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken);
Task<List<ValidationError>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken);
bool Enabled { get; }
string DisabledReason { get; }

View file

@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.Library.Export
public bool ExportPossible(ILibraryAsset libraryItem) => true;
public async Task<List<string>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
public async Task<List<ValidationError>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
{
var firstItem = libraryItems.OfType<ILibraryAsset>().FirstOrDefault();
if (firstItem is ILibraryAsset libraryItem)
@ -72,7 +72,14 @@ namespace MatterHackers.MatterControl.Library.Export
}
}
return new List<string>() { "Item cannot be exported as STL".Localize() + " " + firstItem != null ? firstItem.ToString() : "" };
return new List<ValidationError>()
{
new ValidationError()
{
Error = "Item cannot be exported as STL".Localize(),
Details = firstItem?.ToString() ?? ""
}
};
}
}
}

View file

@ -62,7 +62,7 @@ namespace MatterHackers.MatterControl.Library.Export
public bool ExportPossible(ILibraryAsset libraryItem) => true;
public async Task<List<string>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
public async Task<List<ValidationError>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
{
var streamItems = libraryItems.OfType<ILibraryAssetStream>();
if (streamItems.Any())
@ -101,7 +101,13 @@ namespace MatterHackers.MatterControl.Library.Export
return null;
}
return new List<string>() { "No Items to Export".Localize() };
return new List<ValidationError>()
{
new ValidationError()
{
Error = "No Items to Export".Localize()
}
};
}
}
}

View file

@ -547,10 +547,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if(errors.Count > 0)
{
doSlicing = false;
StyledMessageBox.ShowMessageBox(String.Join("\n__________________\n\n", errors.ToArray()), "Slicing Error".Localize());
// Project to newline separated Error/Details string
var formattedErrors = errors.Select(err => $"{err.Error}\n\n{err.Details}").ToArray();
StyledMessageBox.ShowMessageBox(
string.Join("\n__________________\n\n", formattedErrors),
"Slicing Error".Localize());
}
}
if(doSlicing)
{
activelySlicing = true;

View file

@ -32,6 +32,7 @@ using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.PrinterCommunication;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace MatterHackers.MatterControl.PartPreviewWindow
@ -105,7 +106,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (errors.Count > 0)
{
doSlicing = false;
StyledMessageBox.ShowMessageBox(String.Join("\n__________________\n\n", errors.ToArray()), "Slicing Error".Localize());
// Project to newline separated Error/Details string
var formattedErrors = errors.Select(err => $"{err.Error}\n\n{err.Details}").ToArray();
StyledMessageBox.ShowMessageBox(
string.Join("\n__________________\n\n", formattedErrors),
"Slicing Error".Localize());
}
}

View file

@ -77,7 +77,7 @@ namespace MatterHackers.MatterControl.Plugins.X3GDriver
public override bool ExportPossible(ILibraryAsset libraryItem) => true;
public override async Task<List<string>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
public override async Task<List<ValidationError>> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath, IProgress<ProgressStatus> progress, CancellationToken cancellationToken)
{
string gcodePath = Path.ChangeExtension(outputPath, "_gcode");