// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Threading;
using Tango.Scripting.Editors.Document;
using Tango.Scripting.Editors.Editing;
using System.Windows.Media;
namespace Tango.Scripting.Editors.CodeCompletion
{
/// <summary>
/// The code completion window.
/// </summary>
public class CompletionWindow : CompletionWindowBase
{
readonly CompletionList completionList = new CompletionList();
public event Action<ICompletionData> InsertionRequest;
/// <summary>
/// Gets the completion list used in this completion window.
/// </summary>
public CompletionList CompletionList
{
get { return completionList; }
}
/// <summary>
/// Creates a new code completion window.
/// </summary>
public CompletionWindow(TextArea textArea) : base(textArea)
{
// keep height automatic
this.CloseAutomatically = true;
this.SizeToContent = SizeToContent.WidthAndHeight;
this.WindowStyle = WindowStyle.None;
this.ResizeMode = ResizeMode.NoResize;
this.Content = completionList;
// prevent user from resizing window to 0x0
this.MinHeight = 15;
this.MinWidth = 30;
//this.Background = new SolidColorBrush(Color.FromRgb(15, 15, 15));
this.Foreground = Brushes.Gainsboro;
}
public override void ShowCompletion()
{
base.ShowCompletion();
AttachEvents();
}
public override void HideCompletion()
{
base.HideCompletion();
foreach (var item in completionList.ListBox.Items)
{
var box = completionList.ListBox.ItemContainerGenerator.ContainerFromItem(item) as CompletionListBoxItem;
if (box != null && box.IsSelected)
{
box.toolTip.IsOpen = false;
}
}
}
void completionList_InsertionRequested(object sender, EventArgs e)
{
HideCompletion();
// The window must close before Complete() is called.
// If the Complete callback pushes stacked input handlers, we don't want to pop those when the CC window closes.
var item = completionList.SelectedItem;
//if (item != null)
// item.Complete(this.TextArea, new AnchorSegment(this.TextArea.Document, this.StartOffset, this.EndOffset - this.StartOffset), e);
if (item != null)
{
InsertionRequest?.Invoke(item);
}
completionList.SelectedItem = null;
}
void AttachEvents()
{
this.completionList.InsertionRequested += completionList_InsertionRequested;
this.TextArea.Caret.PositionChanged += CaretPositionChanged;
this.TextArea.MouseWheel += textArea_MouseWheel;
this.TextArea.PreviewTextInput += textArea_PreviewTextInput;
}
/// <inheritdoc/>
protected override void DetachEvents()
{
this.completionList.InsertionRequested -= completionList_InsertionRequested;
this.TextArea.Caret.PositionChanged -= CaretPositionChanged;
this.TextArea.MouseWheel -= textArea_MouseWheel;
this.TextArea.PreviewTextInput -= textArea_PreviewTextInput;
base.DetachEvents();
}
/// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (!e.Handled)
{
completionList.HandleKey(e);
}
}
void textArea_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = RaiseEventPair(this, PreviewTextInputEvent, TextInputEvent,
new TextCompositionEventArgs(e.Device, e.TextComposition));
if (e.Text == " ")
{
HideCompletion();
}
}
void textArea_MouseWheel(object sender, MouseWheelEventArgs e)
{
e.Handled = RaiseEventPair(GetScrollEventTarget(),
PreviewMouseWheelEvent, MouseWheelEvent,
new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta));
}
UIElement GetScrollEventTarget()
{
if (completionList == null)
return this;
return completionList.ScrollViewer ?? completionList.ListBox ?? (UIElement)completionList;
}
/// <summary>
/// Gets/Sets whether the completion window should close automatically.
/// The default value is true.
/// </summary>
public bool CloseAutomatically { get; set; }
/// <inheritdoc/>
protected override bool CloseOnFocusLost
{
get { return this.CloseAutomatically; }
}
/// <summary>
/// When this flag is set, code completion closes if the caret moves to the
/// beginning of the allowed range. This is useful in Ctrl+Space and "complete when typing",
/// but not in dot-completion.
/// Has no effect if CloseAutomatically is false.
/// </summary>
public bool CloseWhenCaretAtBeginning { get; set; }
void CaretPositionChanged(object sender, EventArgs e)
{
int offset = this.TextArea.Caret.Offset;
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using Tango.BL;
using Tango.BL.Builders;
using Tango.BL.Calibration;
using Tango.BL.Entities;
using Tango.Core.Commands;
using Tango.MachineStudio.Common;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.RML.Contracts;
using Tango.MachineStudio.RML.Models;
using Tango.MachineStudio.RML.Views;
using Tango.PMR.ColorLab;
using System.Data.Entity;
using Tango.Core.ExtensionMethods;
using Tango.MachineStudio.Common.Authentication;
using Tango.BL.ActionLogs;
using Tango.BL.DTO;
using Tango.BL.Enumerations;
namespace Tango.MachineStudio.RML.ViewModels
{
public class MainViewVM : StudioViewModel<IMainView>
{
private INotificationProvider _notification;
private IAuthenticationProvider _authentication;
private IActionLogManager _actionLogManager;
private RmlDTO _rmlBeforeSave;
private ObservablesContext _rmls_context;
private ObservablesContext _active_context;
private ObservableCollection<Rml> _rmls;
public ObservableCollection<Rml> Rmls
{
get { return _rmls; }
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
{
get { return _materials; }
set { _materials = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<MediaPurpos> _purposes;
public ObservableCollection<MediaPurpos> Purposes
{
get { return _purposes; }
set { _purposes = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<MediaCondition> _conditions;
public ObservableCollection<MediaCondition> Conditions
{
get { return _conditions; }
set { _conditions = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<LinearMassDensityUnit> _linearMassDensityUnits;
public ObservableCollection<LinearMassDensityUnit> LinearMassDensityUnits
{
get { return _linearMassDensityUnits; }
set { _linearMassDensityUnits = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<FiberShape> _fiberShapes;
public ObservableCollection<FiberShape> FiberShapes
{
get { return _fiberShapes; }
set { _fiberShapes = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<FiberSynth> _fiberSynths;
public ObservableCollection<FiberSynth> FiberSynths
{
get { return _fiberSynths; }
set { _fiberSynths = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<SpoolType> _spoolTypes;
public ObservableCollection<SpoolType> SpoolTypes
{
get { return _spoolTypes; }
set { _spoolTypes = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<BtsrApplicationType> _btsrApplicationTypes;
public ObservableCollection<BtsrApplicationType> BtsrApplicationTypes
{
get { return _btsrApplicationTypes; }
set { _btsrApplicationTypes = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<BtsrYarnType> _btsrYarnTypes;
public ObservableCollection<BtsrYarnType> BtsrYarnTypes
{
get { return _btsrYarnTypes; }
set { _btsrYarnTypes = value; RaisePropertyChangedAuto(); }
}
private Rml _selectedRML;
public Rml SelectedRML
{
get { return _selectedRML; }
set { _selectedRML = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
}
private Rml _activeRML;
public Rml ActiveRML
{
get { return _activeRML; }
set { _activeRML = value; RaisePropertyChangedAuto(); }
}
private CalibrationDataViewVM _calibrationDataViewVM;
public CalibrationDataViewVM CalibrationDataViewVM
{
get { return _calibrationDataViewVM; }
set { _calibrationDataViewVM = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<LiquidTypesRml> _liquidTypesRmls;
public ObservableCollection<LiquidTypesRml> LiquidTypesRmls
{
get { return _liquidTypesRmls; }
set { _liquidTypesRmls = value; RaisePropertyChangedAuto(); }
}
private ProcessParametersTablesGroup _activeProcessParametersGroup;
public ProcessParametersTablesGroup ActiveProcessParametersGroup
{
get { return _activeProcessParametersGroup; }
set { _activeProcessParametersGroup = value; RaisePropertyChangedAuto(); }
}
private ICollectionView _activeProcessParametersTableView;
public ICollectionView ActiveProcessParametersTableView
{
get { return _activeProcessParametersTableView; }
set { _activeProcessParametersTableView = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection<CctModel> _ccts;
public ObservableCollection<CctModel> CCTS
{
get { return _ccts; }
set { _ccts = value; RaisePropertyChangedAuto(); }
}
private CctModel _selectedCCT;
public CctModel SelectedCCT
{
get { return _selectedCCT; }
set { _selectedCCT = value; RaisePropertyChangedAuto(); OnSelectedCCTChanged(); InvalidateRelayCommands(); }
}
private ColorConversionViewVM _colorConversionViewVM;
public ColorConversionViewVM ColorConversionViewVM
{
get { return _colorConversionViewVM; }
set { _colorConversionViewVM = value; RaisePropertyChangedAuto(); }
}
private RmlsSpool _selectedSpool;
public RmlsSpool SelectedSpool
{
get { return _selectedSpool; }
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.
/// </summary>
public RelayCommand ManageRmlCommand { get; set; }
/// <summary>
/// Gets or sets the add RML command.
/// </summary>
public RelayCommand AddRmlCommand { get; set; }
/// <summary>
/// Gets or sets the remove RML command.
/// </summary>
public RelayCommand RemoveRmlCommand { get; set; }
public RelayCommand ImportForwardDataCommand { get; set; }
public RelayCommand ExportForwardDataCommand { get; set; }
public RelayCommand AddProcessParametersTableCommand { get; set; }
public RelayCommand<ProcessParametersTable> RemoveProcessParametersTableCommand { get; set; }
public RelayCommand AddLiquidFactorCommand { get; set; }
public RelayCommand<LiquidTypesRml> RemoveLiquidFactorCommand { get; set; }
public RelayCommand CreateCalibrationDataExcelTemplateCommand { get; set; }
/// <summary>
/// Gets or sets the back to RMLS command.
/// </summary>
public RelayCommand BackToRmlsCommand { get; set; }
public RelayCommand SaveCommand { get; set; }
public RelayCommand CloneRmlCommand { get; set; }
public RelayCommand ExportRMLFileCommand { get; set; }
public RelayCommand ImportRMLFileCommand { get; set; }
/// <summary>
/// Gets or sets the add spool command.
/// </summary>
public RelayCommand AddSpoolCommand { get; set; }
/// <summary>
/// Gets or sets the remove spool command.
/// </summary>
public RelayCommand RemoveSpoolCommand { get; set; }
public MainViewVM(INotificationProvider notificationProvider, IAuthenticationProvider authentication, IActionLogManager actionLogManager)
{
_notification = notificationProvider;
_authentication = authentication;
_actionLogManager = actionLogManager;
ManageRmlCommand = new RelayCommand(() => LoadActiveRML(SelectedRML.Guid), () => SelectedRML != null);
RemoveRmlCommand = new RelayCommand(RemoveSelectedRml, () => SelectedRML != null);
CloneRmlCommand = new RelayCommand(CloneSelectedRml, () => SelectedRML != null);
AddRmlCommand = new RelayCommand(AddNewRml);
BackToRmlsCommand = new RelayCommand(BackToRmls, () => IsFree);
AddProcessParametersTableCommand = new RelayCommand(AddProcessParametersTable, () => IsFree);
RemoveProcessParametersTableCommand = new RelayCommand<ProcessParametersTable>(RemoveProcessParametersTable, () => IsFree);
AddLiquidFactorCommand = new RelayCommand(AddLiquidFactor, () => IsFree);
RemoveLiquidFactorCommand = new RelayCommand<LiquidTypesRml>(RemoveLiquidFactor, () => IsFree);
CreateCalibrationDataExcelTemplateCommand = new RelayCommand(CreateCalibrationDataExcelTemplate);
SaveCommand = new RelayCommand(Save, () => IsFree);
ImportForwardDataCommand = new RelayCommand(ImportCCTData, () => ActiveRML != null && IsFree);
ExportForwardDataCommand = new RelayCommand(ExportCCTData, () => ActiveRML != null && SelectedCCT != null && IsFree);
ExportRMLFileCommand = new RelayCommand(ExportRmlFile, () => SelectedRML != null && IsFree);
ImportRMLFileCommand = new RelayCommand(ImportRmlFile, () => IsFree);
AddSpoolCommand = new RelayCommand(AddNewSpool);
RemoveSpoolCommand = new RelayCommand(RemoveSpool, () => SelectedSpool != null);
}
public override void OnApplicationReady()
{
LoadRmls();
}
private async void LoadRmls()
{
try
{
IsFree = false;
using (_notification.PushTaskItem("Loading Rmls..."))
{
if (_rmls_context != null) _rmls_context.Dispose();
_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);
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) =>
{
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)
{
using (_notification.PushTaskItem("Loading RML..."))
{
try
{
IsFree = false;
if (_active_context != null)
{
_active_context.Dispose();
}
_active_context = ObservablesContext.CreateDefault();
CCTS = _active_context.Ccts
.Select(x => new CctModel()
{
Guid = x.Guid,
FileName = x.FileName,
}).ToObservableCollection();
CCTS.Where(x => String.IsNullOrWhiteSpace(x.FileName)).ToList().ForEach(x => x.FileName = x.Guid);
LoadRmlProperties();
ActiveRML = await new RmlBuilder(_active_context)
.Set(guid)
.WithActiveParametersGroup()
.WithLiquidFactors()
.WithCCT()
.WithSpools()
.BuildAsync();
if (ActiveRML.Cct != null)
{
SelectedCCT = CCTS.SingleOrDefault(x => x.Guid == ActiveRML.Cct.Guid);
}
if (ActiveRML.ProcessParametersTablesGroups.ToList().Count == 0)
{
if (!_notification.ShowQuestion("Could not find any process group for the selected RML. Would you like to create one?"))
{
_notification.ShowError("Cannot load an RML with no process group.");
IsFree = true;
return;
}
else
{
ProcessParametersTablesGroup group = new ProcessParametersTablesGroup();
group.Name = "Active Group";
group.Active = true;
group.ProcessParametersTables.Add(new ProcessParametersTable()
{
Name = "Process Table 1",
});
group.Rml = ActiveRML;
_active_context.ProcessParametersTablesGroups.Add(group);
_active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]);
await _active_context.SaveChangesAsync();
LoadActiveRML(ActiveRML.Guid);
return;
}
}
ActiveProcessParametersGroup = ActiveRML.ProcessParametersTablesGroups.ToList().FirstOrDefault();
ActiveProcessParametersTableView = CollectionViewSource.GetDefaultView(ActiveProcessParametersGroup.ProcessParametersTables);
ActiveProcessParametersTableView.SortDescriptions.Add(new SortDescription(nameof(ProcessParametersTable.TableIndex), ListSortDirection.Ascending));
CalibrationDataViewVM = new CalibrationDataViewVM(_notification);
LiquidTypesRmls = ActiveRML.LiquidTypesRmls;
foreach (var liquidTypeRml in LiquidTypesRmls)
{
CalibrationDataVM catVM = new CalibrationDataVM(liquidTypeRml.LiquidType);
if (liquidTypeRml.DefaultCatData != null)
{
catVM.CalibrationPoints = liquidTypeRml.GetCalibrationData().CalibrationPoints.Select(x => new CalibrationDataPointVM(x.X, x.Y)).ToObservableCollection();
}
CalibrationDataViewVM.LiquidsCalibrationData.Add(catVM);
}
ColorConversionViewVM = new ColorConversionViewVM(_notification)
{
RML = ActiveRML,
CCT = SelectedCCT,
LiquidsCalibrationData = CalibrationDataViewVM.LiquidsCalibrationData,
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);
InvalidateRelayCommands();
IsFree = true;
}
catch (Exception ex)
{
LogManager.Log($"Error loading RML '{ActiveRML.Name}'...");
_notification.ShowError($"Error loading the selected thread.\n{ex.FlattenMessage()}");
}
finally
{
IsFree = true;
}
}
}
private async void OnSelectedCCTChanged()
{
if (SelectedCCT != null && !SelectedCCT.IsNew)
{
using (_notification.PushTaskItem("Loading CCT data..."))
{
IsFree = false;
var cct = await _active_context.Ccts.SingleOrDefaultAsync(x => x.Guid == SelectedCCT.Guid);
if (cct != null)
{
SelectedCCT.Data = cct.Data;
ColorConversionViewVM.CCT = SelectedCCT;
}
IsFree = true;
}
}
}
private void LoadRmlProperties()
{
Materials = _active_context.MediaMaterials.ToObservableCollection();
Purposes = _active_context.MediaPurposes.ToObservableCollection();
Conditions = _active_context.MediaConditions.ToObservableCollection();
LinearMassDensityUnits = _active_context.LinearMassDensityUnits.ToObservableCollection();
FiberShapes = _active_context.FiberShapes.ToObservableCollection();
FiberSynths = _active_context.FiberSynths.ToObservableCollection();
SpoolTypes = _active_context.SpoolTypes.ToObservableCollection();
BtsrApplicationTypes = _active_context.BtsrApplicationTypes.ToObservableCollection();
BtsrYarnTypes = _active_context.BtsrYarnTypes.ToObservableCollection();
}
private async void AddNewRml()
{
var name = _notification.ShowTextInput("Please enter RML name", "Name");
if (!String.IsNullOrWhiteSpace(name))
{
if (Rmls.ToList().Exists(x => x.Name == name))
{
_notification.ShowError("The specified RML name already exists. Please select a different name.");
return;
}
using (_notification.PushTaskItem("Creating new RML..."))
{
IsFree = false;
if (_active_context != null)
{
_active_context.Dispose();
}
_active_context = ObservablesContext.CreateDefault();
LoadRmlProperties();
Rml rml = new Rml();
rml.Name = name;
rml.DisplayName = name;
rml.QualificationDate = DateTime.UtcNow;
rml.Manufacturer = "Twine";
rml.Code = Rmls.Count > 0 ? Rmls.Max(x => x.Code) + 1 : 1;
rml.MediaMaterial = Materials.FirstOrDefault();
rml.MediaPurpose = Purposes.FirstOrDefault();
rml.MediaCondition = Conditions.FirstOrDefault();
rml.LinearMassDensityUnit = LinearMassDensityUnits.FirstOrDefault();
rml.FiberShape = FiberShapes.FirstOrDefault();
rml.FiberSynth = FiberSynths.FirstOrDefault();
ProcessParametersTablesGroup group = new ProcessParametersTablesGroup();
group.Name = "Active Group";
group.Active = true;
group.ProcessParametersTables.Add(new ProcessParametersTable()
{
Name = "Process Table 1",
});
group.Rml = rml;
_active_context.ProcessParametersTablesGroups.Add(group);
_active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]);
_active_context.Rmls.Add(rml);
await _active_context.SaveChangesAsync();
_actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, rml.Name, rml, "Rml created using Machine Studio.");
LoadActiveRML(rml.Guid);
IsFree = true;
}
}
}
private async void RemoveSelectedRml()
{
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?"))
{
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)
{
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.FlattenMessage()}");
LoadRmls();
}
finally
{
IsFree = true;
}
}
}
}
private async void CloneSelectedRml()
{
String name = _notification.ShowTextInput("Enter thread name", "thread name");
if (!String.IsNullOrWhiteSpace(name))
{
using (_notification.PushTaskItem("Cloning thread..."))
{
try
{
IsFree = false;
using (var context = ObservablesContext.CreateDefault())
{
var rml = await new RmlBuilder(context).Set(SelectedRML.Guid).WithActiveParametersGroup().WithLiquidFactors().WithSpools().BuildAsync();
Rml cloned = new Rml();
rml.MapPropertiesTo(cloned, MappingFlags.NoReferenceTypes);
cloned.Code = Rmls.Max(x => x.Code) + 1;
cloned.Guid = Guid.NewGuid().ToString();
cloned.ID = 0;
cloned.Name = name;
cloned.DisplayName = name;
cloned.RmlQualificationLevel = RmlQualifications.Provisional;
cloned.QualificationDate = DateTime.UtcNow;
ProcessParametersTablesGroup group = new ProcessParametersTablesGroup();
group.Name = rml.GetActiveProcessGroup().Name;
group.Active = true;
foreach (var p in rml.GetActiveProcessGroup().ProcessParametersTables)
{
var pc = new ProcessParametersTable();
p.MapPrimitivesTo(pc);
pc.Name = p.Name;
group.ProcessParametersTables.Add(pc);
}
cloned.ProcessParametersTablesGroups.Add(group);
foreach (var liquidFactor in rml.LiquidTypesRmls)
{
LiquidTypesRml l = new LiquidTypesRml();
l.DefaultCatData = liquidFactor.DefaultCatData;
l.LiquidType = liquidFactor.LiquidType;
l.MaxNlPerCm = liquidFactor.MaxNlPerCm;
cloned.LiquidTypesRmls.Add(l);
}
foreach (var spool in rml.RmlsSpools)
{
RmlsSpool s = new RmlsSpool();
spool.MapPropertiesTo(s, MappingFlags.ValueTypesOnly);
s.RmlGuid = cloned.Guid;
s.SpoolTypeGuid = spool.SpoolTypeGuid;
cloned.RmlsSpools.Add(s);
}
context.Rmls.Add(cloned);
await context.SaveChangesAsync();
_actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, cloned.Name, cloned, "RML cloned from Machine Studio.");
}
LoadRmls();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error cloning thread.");
_notification.ShowError($"An error occurred while trying to clone the selected thread\n{ex.Message}");
}
finally
{
IsFree = true;
}
}
}
}
private void AddProcessParametersTable()
{
var name = _notification.ShowTextInput("Enter table name", "Name");
if (!String.IsNullOrWhiteSpace(name))
{
_active_context.ProcessParametersTables.Add(new ProcessParametersTable()
{
ProcessParametersTablesGroup = ActiveProcessParametersGroup,
Name = name,
TableIndex = ActiveProcessParametersGroup.ProcessParametersTables.Max(x => x.TableIndex) + 1,
});
}
}
public void OnProcessParametersTableDropped(ProcessParametersTable dragged, ProcessParametersTable dropped)
{
if (dragged.TableIndex > dropped.TableIndex)
{
dragged.TableIndex = dropped.TableIndex - 1;
}
else
{
dragged.TableIndex = dropped.TableIndex + 1;
}
int index = 0;
foreach (var table in ActiveProcessParametersGroup.ProcessParametersTables.OrderBy(x => x.TableIndex))
{
table.TableIndex = index++;
}
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?"))
{
var catVM = CalibrationDataViewVM.LiquidsCalibrationData.SingleOrDefault(x => x.LiquidType == liquidFactor.LiquidType);
CalibrationDataViewVM.LiquidsCalibrationData.Remove(catVM);
_active_context.LiquidTypesRmls.Remove(liquidFactor);
}
}
private void AddLiquidFactor()
{
AddLiquidFactorViewVM vm = new AddLiquidFactorViewVM(_active_context);
_notification.ShowModalDialog<AddLiquidFactorViewVM, AddLiquidFactorView>(vm, (_) =>
{
if (LiquidTypesRmls.ToList().Exists(x => x.LiquidType == vm.SelectedLiquidType))
{
_notification.ShowError("The selected liquid type is already associated with this RML.");
return;
}
LiquidTypesRml liquidFactor = new LiquidTypesRml()
{
LiquidType = vm.SelectedLiquidType,
Rml = ActiveRML,
};
_active_context.LiquidTypesRmls.Add(liquidFactor);
CalibrationDataVM catVM = new CalibrationDataVM(liquidFactor.LiquidType);
CalibrationDataViewVM.LiquidsCalibrationData.Add(catVM);
}, () => { });
}
private void RemoveProcessParametersTable(ProcessParametersTable processParametersTable)
{
if (ActiveProcessParametersGroup.ProcessParametersTables.Count == 1)
{
_notification.ShowError("The process group must contain at least one table.");
return;
}
if (_notification.ShowQuestion("Are you sure you want to remove this process parameters table?"))
{
_active_context.ProcessParametersTables.Remove(processParametersTable);
}
}
private void CreateCalibrationDataExcelTemplate()
{
SaveFileDialog dlg = new SaveFileDialog();
try
{
dlg.Title = $"Create excel template file";
dlg.Filter = "Excel Files|*.xlsx";
dlg.DefaultExt = ".xlsx";
dlg.FileName = "Calibration File Template";
if (dlg.ShowDialog().Value)
{
CalibrationHelper.CreateCalibrationDataExcelTemplate(dlg.FileName);
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error generating excel calibration template file " + dlg.FileName);
_notification.ShowError("An error occurred while trying to generate the calibration file.");
}
}
private async void Save()
{
IsFree = false;
try
{
using (_notification.PushTaskItem("Saving RML..."))
{
foreach (var calDataVM in CalibrationDataViewVM.LiquidsCalibrationData)
{
var liquidTypeRml = LiquidTypesRmls.SingleOrDefault(x => x.LiquidType == calDataVM.LiquidType);
CalibrationData calData = new CalibrationData();
calData.LiquidType = (PMR.ColorLab.LiquidType)liquidTypeRml.LiquidType.Code;
calData.CalibrationPoints.AddRange(calDataVM.CalibrationPoints.Select(x => new CalibrationPoint() { X = x.X, Y = x.Y }));
liquidTypeRml.PutCalibrationData(calData);
}
ActiveRML.LastUpdated = DateTime.UtcNow;
if (_rmlBeforeSave.QualificationLevel != ActiveRML.QualificationLevel)
{
ActiveRML.QualificationDate = DateTime.UtcNow;
}
if (SelectedCCT != null)
{
if (SelectedCCT.IsNew)
{
Cct cct = new Cct();
cct.Guid = SelectedCCT.Guid;
cct.FileName = SelectedCCT.FileName;
cct.Data = SelectedCCT.Data;
ActiveRML.Cct = cct;
SelectedCCT.IsNew = false;
}
else
{
ActiveRML.CctGuid = SelectedCCT.Guid;
}
}
var rmlAfter = RmlDTO.FromObservable(ActiveRML);
await _active_context.SaveChangesAsync();
_actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlSaved, _authentication.CurrentUser, _rmlBeforeSave.Name, _rmlBeforeSave, rmlAfter, "RML saved using Machine Studio.");
_rmlBeforeSave = rmlAfter;
LoadActiveRML(ActiveRML.Guid);
}
}
catch (Exception ex)
{
LogManager.Log(ex, $"Error saving RML {ActiveRML.Name}");
_notification.ShowError($"An error occurred while trying to save the current RML.\n{ex.FlattenMessage()}");
}
finally
{
IsFree = true;
}
}
private void BackToRmls()
{
View.NavigateTo(RmlNavigationView.RmlsView);
LoadRmls();
}
#region Import / Export Color Conversion Data
private void ImportCCTData()
{
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;
cctModel.FileName = Path.GetFileName(file);
cctModel.Data = File.ReadAllBytes(file);
CCTS.Insert(0, cctModel);
SelectedCCT = cctModel;
ColorConversionViewVM.CCT = SelectedCCT;
}
}
private void ExportCCTData()
{
if (SelectedCCT != null)
{
String file = GetCCTFileSave(ActiveRML.Cct.FileName);
if (file != null)
{
using (_notification.PushTaskItem("Exporting CCT file..."))
{
try
{
IsFree = false;
if (SelectedCCT.IsNew)
{
File.WriteAllBytes(file, SelectedCCT.Data);
}
else
{
var cct = _active_context.Ccts.SingleOrDefault(x => x.Guid == SelectedCCT.Guid);
if (cct != null)
{
File.WriteAllBytes(file, cct.Data);
}
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error exporting CCT file.");
_notification.ShowError($"An error occurred while trying to export the CCT file.\n{ex.Message}");
}
finally
{
IsFree = true;
}
}
}
}
}
private String GetCCTFileOpen()
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Title = "Select color adjustment file";
dlg.Filter = "Color Conversion Table|*.cct";
if (dlg.ShowDialogCenter())
{
return dlg.FileName;
}
return null;
}
private String GetCCTFileSave(String fileName)
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.Title = "Select color adjustment file";
dlg.Filter = "Color Conversion Table|*.cct";
dlg.FileName = fileName;
dlg.DefaultExt = ".cct";
if (dlg.ShowDialogCenter())
{
return dlg.FileName;
}
return null;
}
#endregion
#region RML Import / Export
private async void ImportRmlFile()
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Title = "Import Thread Files";
dlg.Filter = "Twine Thread Files|*.rml";
dlg.Multiselect = true;
if (dlg.ShowDialog().Value)
{
using (_notification.PushTaskItem($"Importing thread files..."))
{
try
{
IsFree = false;
LogManager.Log($"Importing thread files...");
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
foreach (var file in dlg.FileNames)
{
var json = File.ReadAllText(file);
var rmlFile = await Rml.FromRmlFile(db, json);
db.Rmls.Add(rmlFile);
_actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlImported, _authentication.CurrentUser, rmlFile.Name, rmlFile, "RML imported from Machine Studio.");
}
await db.SaveChangesAsync();
}
IsFree = true;
_notification.ShowInfo($"Threads imported successfully.");
LoadRmls();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error importing thread file.");
_notification.ShowError($"An error occurred while trying to import the selected thread file.\n{ex.FlattenMessage()}");
}
finally
{
IsFree = true;
}
}
}
}
private async void ExportRmlFile()
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.Title = "Export Thread File";
dlg.Filter = "Twine Thread Files|*.rml";
dlg.DefaultExt = ".rml";
dlg.FileName = SelectedRML.Name;
if (dlg.ShowDialog().Value)
{
using (_notification.PushTaskItem($"Exporting Thread '{SelectedRML.Name}'..."))
{
try
{
LogManager.Log($"Exporting Thread file {SelectedRML.Name}");
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
var rmlJsonFile = await SelectedRML.ToRmlFile(db);
File.WriteAllText(dlg.FileName, rmlJsonFile);
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error exporting Thread file.");
_notification.ShowError($"An error occurred while trying to export thread '{SelectedRML.Name}'.\n{ex.FlattenMessage()}");
}
}
}
}
#endregion
#region Spools
private void AddNewSpool()
{
_active_context.RmlsSpools.Add(new RmlsSpool()
{
Rml = ActiveRML,
});
}
private void RemoveSpool()
{
if (SelectedSpool != null)
{
_active_context.RmlsSpools.Remove(SelectedSpool);
ActiveRML.RmlsSpools.Remove(SelectedSpool);
}
}
#endregion
}
}