diff options
| author | Shlomo Hecht <shlomo@twine-s.com> | 2020-10-29 15:55:21 +0200 |
|---|---|---|
| committer | Shlomo Hecht <shlomo@twine-s.com> | 2020-10-29 15:55:21 +0200 |
| commit | 4b789f33eadfc5cc1d937a80ce03ea8425955ffe (patch) | |
| tree | 7dbbd0529a24f9ca064cab688a0d6d2b8b762ea1 /Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels | |
| parent | 8f3baa0d9097aa6ed800863a4680608e867c809a (diff) | |
| parent | 11fb700fcbc4627162a9c3f84b03b5016248bd97 (diff) | |
| download | Tango-4b789f33eadfc5cc1d937a80ce03ea8425955ffe.tar.gz Tango-4b789f33eadfc5cc1d937a80ce03ea8425955ffe.zip | |
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels')
6 files changed, 802 insertions, 31 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/CalibrationDataViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/CalibrationDataViewVM.cs index b34ef83bc..fd69fef35 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/CalibrationDataViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/CalibrationDataViewVM.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL.Calibration; +using Tango.BL.Entities; using Tango.Core.Commands; using Tango.MachineStudio.Common; using Tango.MachineStudio.Common.Notifications; @@ -106,5 +107,14 @@ namespace Tango.MachineStudio.RML.ViewModels _notification.ShowError("An error occurred while trying to export the calibration data."); } } + + public void ApplyCalibrationData(LiquidType liquidType, List<CalibrationDataPointVM> newpoints) + { + CalibrationDataVM vm = LiquidsCalibrationData.FirstOrDefault(x => x.LiquidType == liquidType); + if(vm != null) + { + newpoints.ForEach(x => vm.CalibrationPoints.Add(x)); + } + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorCalibrationViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorCalibrationViewVM.cs new file mode 100644 index 000000000..f04eccd90 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorCalibrationViewVM.cs @@ -0,0 +1,551 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core; +using Tango.Core.Commands; +using Tango.MachineStudio.RML.Models; +using Tango.SharedUI; +using OxyPlot; +using OxyPlot.Wpf; +using OxyPlot.Annotations; +using Tango.ColorCalibration; +using Tango.PMR.ColorLab; +using Tango.Logging; +using Tango.MachineStudio.Common.Notifications; +using System.Text.RegularExpressions; +using Microsoft.Win32; + +namespace Tango.MachineStudio.RML.ViewModels +{ + public class ColorCalibrationViewVM : ExtendedObject + { + private IColorCalibrator _calibrator; + private ILinearizationMeasurements _linearizationMeasurementscalibrator; + private INotificationProvider _notification; + + #region Properties + + private Rml _rml; + public Rml RML + { + get { return _rml; } + set { _rml = value; RaisePropertyChangedAuto(); } + } + + private BL.Entities.LiquidType _liquidType; + + public BL.Entities.LiquidType LiquidType + { + get { return _liquidType; } + set { _liquidType = value; RaisePropertyChangedAuto(); RaisePropertyChanged("LiquidTypeName"); } + } + + private List<BL.Entities.LiquidType> _liquidTypes; + + public List<BL.Entities.LiquidType> LiquidTypes + { + get { return _liquidTypes; } + set { _liquidTypes = value; } + } + + + private ObservableCollection<CalibrationMeasurementModel> _measurements; + public ObservableCollection<CalibrationMeasurementModel> Measurements + { + get + { + return _measurements; + } + set + { + _measurements = value; RaisePropertyChangedAuto(); + } + } + + + private double _factor; + + public double Factor + { + get { return _factor; } + set { _factor = value; RaisePropertyChangedAuto(); } + } + + private string _errorMessage; + + public string ErrorMessage + { + get { return _errorMessage; } + set { _errorMessage = value; RaisePropertyChangedAuto(); } + } + private bool _hasError; + + public bool HasError + { + get { return _hasError; } + set { _hasError = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand ImportDataCommand { get; set; } + public RelayCommand CreateGraphCommand { get; set; } + public RelayCommand CreateLinearizationGraphCommand { get; set; } + public RelayCommand ExportGraphCommand { get; set; } + public RelayCommand ApplyCalibrationDataCommand { get; set; } + + + public string LiquidTypeName + { + get { return LiquidType == null ?"" : LiquidType.Name; } + } + + public Plot PlotControl { get; set; } + private IList<DataPoint> _points; + /// <summary> + /// Binding to ItemsSource of line chart. + /// </summary> + public IList<DataPoint> Points + { + get { return _points; } + set + { + _points = value; + RaisePropertyChangedAuto(); + } + } + private IList<DataPoint> _targetPoints; + /// <summary> + /// Binding to ItemsSource of line chart. + /// </summary> + public IList<DataPoint> TargetPoints + { + get { return _targetPoints; } + set + { + _targetPoints = value; + RaisePropertyChangedAuto(); + } + } + private int _step; + public int XStep + { + get { return _step; } + set { _step = value; RaisePropertyChangedAuto(); } + } + + private double _from; + /// <summary> + /// From use to binding to bottom axis min value + /// </summary> + public double From + { + get { return _from; } + set + { + _from = value; RaisePropertyChangedAuto(); + } + } + + private double _to; + /// <summary> + /// To use to binding to bottom axis max value + /// </summary> + public double To + { + get { return _to; } + set + { + _to = value; RaisePropertyChangedAuto(); + } + } + + private double _LabMinVal; + + public double LabMinVal + { + get { return _LabMinVal; } + set { _LabMinVal = value; RaisePropertyChangedAuto(); } + } + + private double _LabMaxVal; + + public double LabMaxVal + { + get { return _LabMaxVal; } + set { _LabMaxVal = value; RaisePropertyChangedAuto(); } + } + + public Plot LABLinearizationPlotControl { get; set; } + public Plot LinearizationPlotControl { get; set; } + private IList<DataPoint> _linearizationPoints; + /// <summary> + /// Binding to ItemsSource of line chart. + /// </summary> + public IList<DataPoint> LinearizationPoints + { + get { return _linearizationPoints; } + set + { + _linearizationPoints = value; + RaisePropertyChangedAuto(); + } + } + + private IList<DataPoint> _LPoints; + + public IList<DataPoint> LPoints + { + get { return _LPoints; } + set { _LPoints = value; } + } + + private IList<DataPoint> _APoints; + + public IList<DataPoint> APoints + { + get { return _APoints; } + set { _APoints = value; } + } + + private IList<DataPoint> _BPoints; + + public IList<DataPoint> BPoints + { + get { return _BPoints; } + set { _BPoints = value; } + } + + + #endregion + + public ColorCalibrationViewVM(INotificationProvider notification) + { + _notification = notification; + Measurements = new ObservableCollection<CalibrationMeasurementModel>() + { + new CalibrationMeasurementModel(), + new CalibrationMeasurementModel(), + new CalibrationMeasurementModel(), + }; + Factor = 0; + HasError = false; + ImportDataCommand = new RelayCommand(ImportDataForCalcFactorExcel); + CreateGraphCommand = new RelayCommand(CreateGraph); + CreateLinearizationGraphCommand = new RelayCommand(CreateLinearizationGraph); + ExportGraphCommand = new RelayCommand(ExportGraph); + ApplyCalibrationDataCommand = new RelayCommand(ApplyCalibrationData); + this.Points = new List<DataPoint>(); + TargetPoints = new List<DataPoint>(); + LinearizationPoints = new List<DataPoint>(); + LPoints = new List<DataPoint>(); + APoints = new List<DataPoint>(); + BPoints = new List<DataPoint>(); + } + + public void Loading() + { + LiquidType = LiquidTypes.Count > 0 ? LiquidTypes[0] : null; + _calibrator = new DefaultColorCalibrator(); + _linearizationMeasurementscalibrator = new DefaultColorCalibrator(); + + } + + public void ClearResults() + { + Points.Clear(); + TargetPoints.Clear(); + ErrorMessage = ""; + HasError = false; + Factor = 0.0; + } + + private double GetLiquidFactor() + { + try + { + CalibrationInput conversionInput = new CalibrationInput(); + Measurements.ToList().ForEach(x => conversionInput.Measurements.Add(new CalibrationMeasurement { L = x.L, A = x.A, B = x.B, NanoliterPerCentimeter = x.Ink })); + conversionInput.LiquidType = PMR.ColorLab.LiquidType.TryParse(_liquidType.Type.ToString(), out PMR.ColorLab.LiquidType outValue) ? outValue : PMR.ColorLab.LiquidType.Black; + + + LAB lab; + if (ColorCalibrationExt.TargetLiquidTypeToLAB.TryGetValue(_liquidType.Type, out lab)) + { + conversionInput.TargetL = lab.L; + conversionInput.TargetA = lab.A; + conversionInput.TargetB = lab.B; + } + CalibrationOutput result = _calibrator.GetLiquidFactor(conversionInput); + + ErrorMessage = result.ErrorMessage; + HasError = false == String.IsNullOrEmpty(ErrorMessage); + + return result.LiquidFactor; + } + catch (Exception ex ) + { + HasError = true; + ErrorMessage = "Error occurred while trying to call GetLiquidFactor."; + LogManager.Log(ex, "Error occurred while trying to call GetLiquidFactor."); + } + return 0.0; + } + + private void ImportDataForCalcFactorExcel() + { + OpenFileDialog dlg = new OpenFileDialog(); + + try + { + dlg.Title = $"Import excel file for calculate Factor"; + dlg.Filter = "Excel Files|*.xlsx"; + if (dlg.ShowDialog().Value) + { + ClearResults(); + + List<ColorLinearizationModel.LinearizationDataItem> items;//List<LinearizationDataItem> items + ColorLinearizationModel model = new ColorLinearizationModel(); + string error = ""; + model.GetDataFromFile(dlg.FileName, out items, ref error); + if (false == String.IsNullOrEmpty(error) || items == null || items.Count == 0) + { + _notification.ShowError("An error occurred while trying to import data form the selected excel file. Please check the file format if valid and is available to read."); + return; + } + Measurements.Clear(); + items.ForEach(x => Measurements.Add(new CalibrationMeasurementModel(x))); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error importing excel file " + dlg.FileName); + _notification.ShowError("An error occurred while trying to import the selected excel file. Please check the file format if valid and is available to read."); + } + } + #region CreateGraph + + private async void CreateGraph(object obj) + { + if (_liquidType == null) + return; + ClearResults(); + PlotControl.InvalidatePlot(true); + string labType = ColorCalibrationExt.DisplayLiquidTypeToLABType[_liquidType.Type]; + await Task.Factory.StartNew(() => + { + Factor = GetLiquidFactor( ); + }); + + DataPoint targetPoint = GetTargetPoint(); + + To = 0; + From = 0; + + Measurements.ToList().ForEach(x =>{ Points.Add(new DataPoint(x.Ink, labType == "L" ? x.L : x.B)); + TargetPoints.Add(new DataPoint(x.Ink, targetPoint.Y)); }); + + _to = labType == "L"? 100 : 128; + _from = labType == "L" ? 0 : -127; + + RaisePropertyChanged("To"); + RaisePropertyChanged("From"); + XStep = (int)(Points.Count / 6); + RaisePropertyChanged("CalibrationType"); + PlotControl.InvalidatePlot(true); + + } + + private DataPoint GetTargetPoint() + { + var listValues = Measurements.ToList(); + if (listValues.Count == 0 || Factor <=0) + return new DataPoint(0, 0); + + string labType = ColorCalibrationExt.DisplayLiquidTypeToLABType[_liquidType.Type]; + + var left = listValues.Where(y => y.Ink == listValues.Min(x => x.Ink)).ToList().First(); + var right = listValues.Where(y => y.Ink == listValues.Max(x => x.Ink)).ToList().First(); + // Normalize start/end to left right to make the offset calc simpler. + DataPoint leftPoint = new DataPoint(left.Ink, labType == "L" ? left.L : left.B); + DataPoint rightPoint = new DataPoint(right.Ink, labType == "L" ? right.L : right.B); + + double deltaX = rightPoint.X - leftPoint.X; + double deltaY = rightPoint.Y - leftPoint.Y; + + // prevents division by zero exceptions. + if (deltaX == 0 ) + return new DataPoint(0, 0); + + double slope = deltaY / deltaX; + double offset = leftPoint.Y - leftPoint.X * slope; + double calculatedY = Factor * slope + offset; + + return new DataPoint(Factor, calculatedY); ; + } + + #endregion + #region CreateLinearizationGraph + + private async void CreateLinearizationGraph(object obj) + { + if (_liquidType == null ) + return; + + string labType = ColorCalibrationExt.DisplayLiquidTypeToLABType[_liquidType.Type]; + + ColorLinearizationModel model = new ColorLinearizationModel(); + string fileName = GetInkDataFileOpen();// @"C:\Test\Test Input Lineration.xlsx";//dialog to open file + if (fileName == null) + return; + + LinearizationPoints.Clear(); + LinearizationPlotControl.InvalidatePlot(true); + LPoints.Clear(); + APoints.Clear(); + BPoints.Clear(); + LabMinVal = LabMaxVal = 0; + LABLinearizationPlotControl.InvalidatePlot(true); + + List<ColorLinearizationModel.LinearizationDataItem> items; + string errors = ""; + model.GetDataFromFile(fileName, out items, ref errors); + if(false == String.IsNullOrEmpty(errors) || items == null || items.Count == 0) + { + _notification.ShowError("An error occurred while trying to import data form the selected excel file. Please check the file format if valid and is available to read."); + return; + } + + List<double> outputPoints = new List<double>(); + + await Task.Factory.StartNew(() => + { + outputPoints = GetLinearizationMeasurements(items); + }); + + LabMinVal = items.Min(x => Math.Min(x.L, Math.Min(x.A, x.B))); + LabMaxVal = items.Max(x => Math.Max(x.L, Math.Max(x.A, x.B))); + foreach (var labItem in items) + { + LPoints.Add(new DataPoint(labItem.InkPercentage, labItem.L)); + APoints.Add(new DataPoint(labItem.InkPercentage, labItem.A)); + BPoints.Add(new DataPoint(labItem.InkPercentage, labItem.B)); + } + LABLinearizationPlotControl.InvalidatePlot(true); + + if (outputPoints == null || outputPoints.Count != items.Count) + return; + + foreach (var nw in items.Zip(outputPoints, Tuple.Create)) + { + LinearizationPoints.Add(new DataPoint(nw.Item1.InkPercentage, nw.Item2)); + } + + LinearizationPlotControl.InvalidatePlot(true); + } + + /// <summary> + /// Open file dialog and get name of file + /// </summary> + /// <returns></returns> + private String GetInkDataFileOpen() + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Title = "Select Ink data file"; + dlg.Filter = "Excel |*.xlsx"; + if (dlg.ShowDialogCenter()) + { + return dlg.FileName; + } + + return null; + } + + private List<double> GetLinearizationMeasurements(List<ColorLinearizationModel.LinearizationDataItem> items) + { + try + { + LinearizationInput linearizationInput = new LinearizationInput(); + items.ForEach(x => linearizationInput.Measurements.Add(new LinearizationMeasurement { L = x.L, A = x.A, B = x.B, InkPercentage = x.InkPercentage })); + linearizationInput.LiquidType = PMR.ColorLab.LiquidType.TryParse(_liquidType.Type.ToString(), out PMR.ColorLab.LiquidType outValue) ? outValue : PMR.ColorLab.LiquidType.Black; + + LinearizationOutput result = _linearizationMeasurementscalibrator.GetLinearizationMeasurements(linearizationInput); + + if(!String.IsNullOrEmpty(result.ErrorMessage)) + { + LogManager.Log(result.ErrorMessage, "GetLinearizationMeasurements returns error." + result.ErrorMessage); + InvokeUI(() => + { + _notification.ShowError("Linearization failed. " + result.ErrorMessage); + }); + } + + LAB lab; + if (ColorCalibrationExt.TargetLiquidTypeToLAB.TryGetValue(_liquidType.Type, out lab)) + { + linearizationInput.TargetL = lab.L; + linearizationInput.TargetA = lab.A; + linearizationInput.TargetB = lab.B; + } + return result.InkPercentage.ToList(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to call GetLinearizationMeasurements."); + } + return null; + } + #endregion + + #region Export graph + /// <summary> + /// Exports the graph point to Excel file. + /// </summary> + protected void ExportGraph() + { + SaveFileDialog dlg = new SaveFileDialog(); + try + { + dlg.Title = $"Export excel calibration file for {LiquidType.Name}"; + dlg.Filter = "Excel Files|*.xlsx"; + dlg.DefaultExt = ".xlsx"; + dlg.FileName = $"CData_{LiquidType.Name}_v{LiquidType.Version}.xlsx"; + if (dlg.ShowDialog().Value) + { + List<CalibrationPoint> points = new List<CalibrationPoint>(); + LinearizationPoints.ToList().ForEach(x=> points.Add(ToCalibrationPoint(x))); + BL.Calibration.CalibrationHelper.ExportCalibrationDataToExcel(points, dlg.FileName); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error exporting excel file " + dlg.FileName); + _notification.ShowError("An error occurred while trying to export the calibration data."); + } + } + public CalibrationPoint ToCalibrationPoint(DataPoint point) + { + return new CalibrationPoint() + { + X = point.X, + Y = point.Y, + }; + } + + /// <summary> + /// Applies the calibration data. + /// </summary> + protected void ApplyCalibrationData() + { + if (LinearizationPoints.Count == 0) + return; + + List<CalibrationDataPointVM> points = new List<CalibrationDataPointVM>(); + LinearizationPoints.ToList().ForEach(x => points.Add(new CalibrationDataPointVM(x.X, x.Y))); + ViewModelLocator.MainViewVM.CalibrationDataViewVM.ApplyCalibrationData(LiquidType, points); + } + #endregion + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs index f583fa15e..95de19f42 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs @@ -111,6 +111,7 @@ namespace Tango.MachineStudio.RML.ViewModels Color = x.LiquidType.Color, Name = x.LiquidType.Name, LiquidType = x.LiquidType, + MaxNanoliterPerCentimeter = x.MaxNlPerCm, }).ToObservableCollection(); } @@ -309,16 +310,16 @@ namespace Tango.MachineStudio.RML.ViewModels } } - private double GetTotalMaximumLiquidVolumeLimit() + private double GetTotalMaximumLiquidNlPerCMLimit() { try { var tables = RML.GetActiveProcessGroup().ProcessParametersTables.OrderBy(x => x.TableIndex).ToList(); - return (tables[1].MaxInkUptake / tables[0].MaxInkUptake) * 100; + return tables.Max(x => x.MaxInkUptake); } catch { - return BrushStop.MAX_TOTAL_LIQUID_VOLUME; + return BrushStop.MAX_INK_UPTAKE; } } @@ -329,7 +330,7 @@ namespace Tango.MachineStudio.RML.ViewModels if (LiquidsCalibrationData == null || _prevent_inverse_conversion) return; //TODO: This is temporary because of out of range volumes. - if (LiquidVolumes.Where(x => x.LiquidType.HasPigment).Sum(x => x.Volume) > GetTotalMaximumLiquidVolumeLimit()) + if (LiquidVolumes.Where(x => x.LiquidType.HasPigment).Sum(x => x.NanoliterPerCentimeter) > GetTotalMaximumLiquidNlPerCMLimit()) { IsVolumesOutOfRange = true; return; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/LiquidVolumeVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/LiquidVolumeVM.cs index 7399d62af..27b811bb6 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/LiquidVolumeVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/LiquidVolumeVM.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Dispensing; using Tango.BL.Entities; using Tango.Core; using Tango.SharedUI; @@ -47,5 +48,17 @@ namespace Tango.MachineStudio.RML.ViewModels get { return _liquidType; } set { _liquidType = value; RaisePropertyChangedAuto(); } } + + public double MaxNanoliterPerCentimeter { get; set; } + + public double NanoliterPerCentimeter + { + get + { + StandardColorDispensingCalc calc = new StandardColorDispensingCalc(); + return calc.CalculateNanoliterPerCentimeter(Volume, MaxNanoliterPerCentimeter); + } + } + } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs index 1ceaf07df..cadd1fb95 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs @@ -45,6 +45,20 @@ namespace Tango.MachineStudio.RML.ViewModels set { _rmls = value; RaisePropertyChangedAuto(); } } + private ICollectionView _rmlssCollectionView; + /// <summary> + /// Gets or sets the RML collection view. + /// </summary> + public ICollectionView RmlsCollectionView + { + get { return _rmlssCollectionView; } + set + { + _rmlssCollectionView = value; + RaisePropertyChangedAuto(); + } + } + private ObservableCollection<MediaMaterial> _materials; public ObservableCollection<MediaMaterial> Materials { @@ -164,6 +178,22 @@ namespace Tango.MachineStudio.RML.ViewModels set { _selectedSpool = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } + private ColorCalibrationViewVM _colorCalibrationVM; + public ColorCalibrationViewVM ColorCalibrationVM + { + get { return _colorCalibrationVM; } + set { _colorCalibrationVM = value; RaisePropertyChangedAuto(); } + } + + private String _RMLFilter; + /// <summary> + /// Gets or sets the job filter. + /// </summary> + public String RMLFilter + { + get { return _RMLFilter; } + set { _RMLFilter = value; RaisePropertyChangedAuto(); OnRMLFilterChanged(); } + } /// <summary> /// Gets or sets the manage RML command. @@ -252,31 +282,57 @@ namespace Tango.MachineStudio.RML.ViewModels private async void LoadRmls() { - if (_rmls_context != null) _rmls_context.Dispose(); + try + { + IsFree = false; - _rmls_context = ObservablesContext.CreateDefault(); - Rmls = await new RmlsCollectionBuilder(_rmls_context).SetAll().WithLiquidFactors().WithMediaProperties().BuildAsync(); + using (_notification.PushTaskItem("Loading Rmls...")) + { + if (_rmls_context != null) _rmls_context.Dispose(); - //Load CCT file names... - var ccts = await _rmls_context.Ccts.Select(x => new - { - x.Guid, - x.FileName - }).ToListAsync(); + _rmls_context = ObservablesContext.CreateDefault(); + Rmls = await new RmlsCollectionBuilder(_rmls_context).SetAll().WithLiquidFactors().WithMediaProperties().BuildAsync(); + //Load CCT file names... + var ccts = await _rmls_context.Ccts.Select(x => new + { + x.Guid, + x.FileName + }).ToListAsync(); - foreach (var rml in Rmls) - { - var cct = ccts.SingleOrDefault(x => x.Guid == rml.CctGuid); + foreach (var rml in Rmls) + { + var cct = ccts.SingleOrDefault(x => x.Guid == rml.CctGuid); - if (cct != null) - { - rml.Cct = new Cct() + if (cct != null) + { + rml.Cct = new Cct() + { + Guid = cct.Guid, + FileName = cct.FileName, + }; + } + } + RmlsCollectionView = CollectionViewSource.GetDefaultView(Rmls); + RmlsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Rml.LastUpdated), ListSortDirection.Descending)); + //RmlsCollectionView.Filter = new Predicate<object>(FilterCollection); + + RmlsCollectionView.Filter = (rml) => { - Guid = cct.Guid, - FileName = cct.FileName, + Rml r = rml as Rml; + return String.IsNullOrWhiteSpace(RMLFilter) + || r.Name.ToLower().Contains(RMLFilter.ToLower()); }; + } } + catch (Exception ex) + { + LogManager.Log(ex, $"Error loading RMLS.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } } private async void LoadActiveRML(String guid) @@ -374,6 +430,12 @@ namespace Tango.MachineStudio.RML.ViewModels LiquidTypesRmls = LiquidTypesRmls, }; + ColorCalibrationVM = new ColorCalibrationViewVM(_notification) + { + RML = ActiveRML, + LiquidTypes = LiquidTypesRmls.Where(x => x.LiquidType.HasPigment).ToList().Select(y => y.LiquidType).ToList(), + }; + _rmlBeforeSave = RmlDTO.FromObservable(ActiveRML); View.NavigateTo(RmlNavigationView.RmlView); @@ -456,7 +518,7 @@ namespace Tango.MachineStudio.RML.ViewModels rml.DisplayName = name; rml.QualificationDate = DateTime.UtcNow; rml.Manufacturer = "Twine"; - rml.Code = Rmls.Max(x => x.Code) + 1; + rml.Code = Rmls.Count > 0 ? Rmls.Max(x => x.Code) + 1 : 1; rml.MediaMaterial = Materials.FirstOrDefault(); rml.MediaPurpose = Purposes.FirstOrDefault(); rml.MediaCondition = Conditions.FirstOrDefault(); @@ -492,34 +554,62 @@ namespace Tango.MachineStudio.RML.ViewModels { if (_notification.ShowQuestion("Removing the selected thread will result in the loss of all related process parameters and default calibration data. Are you sure you want to delete the selected RML?")) { - IsFree = false; - using (_notification.PushTaskItem("Removing RML...")) { try { + IsFree = false; + var rml_jobs = await _rmls_context.Jobs.Where(x => x.RmlGuid == SelectedRML.Guid).Include(x => x.Machine).OrderBy(x => x.Machine.SerialNumber).ToListAsync(); if (rml_jobs.Count > 0) { - _notification.ShowError($"The following jobs must be removed or change thread type before the selected thread can be deleted:\n{String.Join("\n", rml_jobs.Select(x => $"{x.Machine.SerialNumber} => {x.Name}"))}"); - return; + var vm = new RmlDeleteDialogViewVM(SelectedRML, Rmls.ToList(), rml_jobs.ToList()); + _notification.ShowModalDialog<RmlDeleteDialogViewVM, RmlDeleteDialogView>(vm, (x) => { }, () => { }); + + if (!vm.DialogResult) + { + return; + } + + //Perform actions... + using (var db = ObservablesContext.CreateDefault()) + { + foreach (var jobAction in vm.JobsActions) + { + if (jobAction.Action == RmlDeleteDialogViewVM.RmlDeleteJobAction.Delete) + { + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.JobDeleted, _authentication.CurrentUser.Guid, jobAction.Job.Name, jobAction.Job.Guid, $"Job deleted due to RML '{SelectedRML.Name}' being removed."); + await jobAction.Job.DeleteCascadeAsync(db); + } + else if (jobAction.Action == RmlDeleteDialogViewVM.RmlDeleteJobAction.Change) + { + var job = await db.Jobs.SingleOrDefaultAsync(x => x.Guid == jobAction.Job.Guid); + job.RmlGuid = jobAction.TargetRml.Guid; + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.JobSaved, _authentication.CurrentUser.Guid, jobAction.Job.Name, jobAction.Job.Guid, $"Job RML changed to '{jobAction.TargetRml.Name}' due to RML '{SelectedRML.Name}' being removed."); + } + } + + await db.SaveChangesAsync(); + } } await SelectedRML.DeleteCascadeAsync(_rmls_context); - _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlDeleted, _authentication.CurrentUser, SelectedRML.Name, SelectedRML, "RML deleted from Machine Studio."); LoadRmls(); } catch (Exception ex) { - LogManager.Log(ex, $"Error removing selected RML {SelectedRML.Name}."); - _notification.ShowError($"An error occurred while trying to remove the selected RML.\n{ex.Message}"); + LogManager.Log(ex, $"Error removing selected RML {SelectedRML?.Name}."); + _notification.ShowError($"An error occurred while trying to remove the selected RML.\n{ex.FlattenMessage()}"); + LoadRmls(); + } + finally + { + IsFree = true; } } - - IsFree = true; } } @@ -641,6 +731,11 @@ namespace Tango.MachineStudio.RML.ViewModels ActiveProcessParametersTableView.Refresh(); } + private void OnRMLFilterChanged() + { + RmlsCollectionView.Refresh(); + } + private void RemoveLiquidFactor(LiquidTypesRml liquidFactor) { if (_notification.ShowQuestion("Removing this liquid factor will remove the liquid type association with the RML and will drop the calibration data. Are you sure?")) @@ -788,6 +883,12 @@ namespace Tango.MachineStudio.RML.ViewModels String file = GetCCTFileOpen(); if (file != null) { + if (CCTS.ToList().Exists(x => x.FileName == Path.GetFileName(file))) + { + _notification.ShowError("The selected CCT file already exists on the database. Please select the CCT file from the dropdown box."); + return; + } + CctModel cctModel = new CctModel(); cctModel.Guid = Guid.NewGuid().ToString(); cctModel.IsNew = true; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/RmlDeleteDialogViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/RmlDeleteDialogViewVM.cs new file mode 100644 index 000000000..b4c6c6274 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/RmlDeleteDialogViewVM.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core; +using Tango.SharedUI; + +namespace Tango.MachineStudio.RML.ViewModels +{ + public class RmlDeleteDialogViewVM : DialogViewVM + { + public enum RmlDeleteJobAction + { + Delete, + Change + } + + public class RmlDeleteJob : ExtendedObject + { + public Job Job { get; set; } + public Machine Machine { get; set; } + private RmlDeleteJobAction _action; + + public RmlDeleteJobAction Action + { + get { return _action; } + set { _action = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(IsDelete)); } + } + + public bool IsDelete + { + get { return Action == RmlDeleteJobAction.Delete; } + } + + + public Rml TargetRml { get; set; } + + public override string ToString() + { + return $"{Machine.SerialNumber} => {Job.Name} => {Action} {(Action == RmlDeleteJobAction.Change ? $" => {TargetRml.Name}" : String.Empty)}"; + } + } + + private List<Job> _jobsToDelete; + + private List<RmlDeleteJob> _jobsActions; + public List<RmlDeleteJob> JobsActions + { + get { return _jobsActions; } + set { _jobsActions = value; RaisePropertyChangedAuto(); } + } + + public Rml Rml { get; set; } + + public List<Rml> Rmls { get; set; } + + public List<RmlDeleteJobAction> Actions { get; set; } + + public RmlDeleteDialogViewVM(Rml rml, List<Rml> rmls, List<Job> jobsToDelete) + { + Rml = rml; + Rmls = rmls.Where(x => x.Guid != rml.Guid).ToList(); + _jobsToDelete = jobsToDelete; + JobsActions = new List<RmlDeleteJob>(); + + Actions = new List<RmlDeleteJobAction>() + { + RmlDeleteJobAction.Delete, + RmlDeleteJobAction.Change + }; + } + + public override void OnShow() + { + base.OnShow(); + + List<RmlDeleteJob> list = new List<RmlDeleteJob>(); + + foreach (var job in _jobsToDelete) + { + RmlDeleteJob deleteJob = new RmlDeleteJob(); + deleteJob.Job = job; + deleteJob.Action = RmlDeleteJobAction.Delete; + deleteJob.Machine = job.Machine; + deleteJob.TargetRml = Rmls.FirstOrDefault(x => x.Guid != Rml.Guid); + + list.Add(deleteJob); + } + + JobsActions = list; + } + } +} |
