aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs')
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs1567
1 files changed, 1567 insertions, 0 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs
new file mode 100644
index 000000000..cf66efbd6
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs
@@ -0,0 +1,1567 @@
+using GalaSoft.MvvmLight.Ioc;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using System.Windows.Media;
+using Tango.Core.Commands;
+using Tango.Integration.Observables;
+using Tango.Integration.Operators;
+using Tango.Integration.Services;
+using Tango.Logging;
+using Tango.MachineStudio.Common.Authentication;
+using Tango.MachineStudio.Common.Controls;
+using Tango.MachineStudio.Common.Diagnostics;
+using Tango.MachineStudio.Common.Notifications;
+using Tango.MachineStudio.Common.StudioApplication;
+using Tango.MachineStudio.Common.Video;
+using Tango.MachineStudio.Developer.Navigation;
+using Tango.MachineStudio.Developer.Views;
+using Tango.Settings;
+using Tango.SharedUI;
+using Tango.Transport;
+
+namespace Tango.MachineStudio.Developer.ViewModels
+{
+ /// <summary>
+ /// Represents the developer module main view, view model.
+ /// </summary>
+ /// <seealso cref="Tango.SharedUI.ViewModel" />
+ public class MainViewVM : ViewModel<IMainView>, IShutdownRequestBlocker, IShutdownListener
+ {
+ private static object _syncLock = new object();
+
+ private INotificationProvider _notification;
+ private TimeSpan _runningJobEstimatedDuration;
+ private JobHandler _jobHandler;
+ private DeveloperNavigationManager _navigation;
+ private bool _blockInvalidateCommands;
+ private IAuthenticationProvider _authentication;
+ private ObservablesContext _machineDbContext;
+ private ObservablesContext _activeJobDbContext;
+
+ #region Properties
+
+ private ObservableCollection<Machine> _machines;
+ /// <summary>
+ /// Gets or sets the machines.
+ /// </summary>
+ public ObservableCollection<Machine> Machines
+ {
+ get { return _machines; }
+ set { _machines = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ObservableCollection<ColorSpace> _colorSpaces;
+ /// <summary>
+ /// Gets or sets the color spaces.
+ /// </summary>
+ public ObservableCollection<ColorSpace> ColorSpaces
+ {
+ get { return _colorSpaces; }
+ set { _colorSpaces = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ObservableCollection<Rml> _rmls;
+ /// <summary>
+ /// Gets or sets the RMLS.
+ /// </summary>
+ public ObservableCollection<Rml> Rmls
+ {
+ get { return _rmls; }
+ set { _rmls = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ObservableCollection<WindingMethod> _windingMethods;
+ /// <summary>
+ /// Gets or sets the winding methods.
+ /// </summary>
+ public ObservableCollection<WindingMethod> WindingMethods
+ {
+ get { return _windingMethods; }
+ set { _windingMethods = value; RaisePropertyChangedAuto(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the application manager.
+ /// </summary>
+ public IStudioApplicationManager ApplicationManager { get; set; }
+
+ /// <summary>
+ /// Gets or sets the video capture provider.
+ /// </summary>
+ public IVideoCaptureProvider VideoCaptureProvider { get; set; }
+
+ protected Machine _selectedMachine;
+ /// <summary>
+ /// Gets or sets the selected machine.
+ /// </summary>
+ public Machine SelectedMachine
+ {
+ get { return _selectedMachine; }
+ set
+ {
+ _selectedMachine = value;
+ OnSelectedMachineChanged();
+ RaisePropertyChangedAuto();
+ InvalidateRelayCommands();
+
+ if (_selectedMachine != null)
+ {
+ _selectedMachine.Saved -= SelectedMachine_Saved;
+ _selectedMachine.Saved += SelectedMachine_Saved;
+ }
+ }
+ }
+
+ private List<LiquidTypesRml> _liquidTypesRmls;
+ /// <summary>
+ /// Gets or sets the liquid types RMLS.
+ /// </summary>
+ public List<LiquidTypesRml> LiquidTypesRmls
+ {
+ get { return _liquidTypesRmls; }
+ set { _liquidTypesRmls = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ProcessParametersTablesGroup _rmlProcessParametersTablesGroup;
+ /// <summary>
+ /// Gets or sets the RML process parameters table group (cloned).
+ /// </summary>
+ public ProcessParametersTablesGroup RmlProcessParametersTableGroup
+ {
+ get { return _rmlProcessParametersTablesGroup; }
+ set
+ { _rmlProcessParametersTablesGroup = value; RaisePropertyChangedAuto(); OnProcessParametersTableGroupChanged(); }
+ }
+
+ private ObservableCollection<ProcessParametersTablesGroup> _groupsHistory;
+ /// <summary>
+ /// Gets or sets the RML process parameters groups history.
+ /// </summary>
+ public ObservableCollection<ProcessParametersTablesGroup> GroupsHistory
+ {
+ get { return _groupsHistory; }
+ set { _groupsHistory = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ProcessParametersTablesGroup _selectedGroupHistory;
+ /// <summary>
+ /// Gets or sets the selected process parameters tables group history.
+ /// </summary>
+ public ProcessParametersTablesGroup SelectedGroupHistory
+ {
+ get { return _selectedGroupHistory; }
+ set { _selectedGroupHistory = value; RaisePropertyChangedAuto(); OnSelectedGroupHistoryChanged(); }
+ }
+
+ private ProcessParametersTable _selectedProcessParametersTable;
+ /// <summary>
+ /// Gets or sets the selected process parameters table.
+ /// </summary>
+ public ProcessParametersTable SelectedProcessParametersTable
+ {
+ get { return _selectedProcessParametersTable; }
+ set { _selectedProcessParametersTable = value; RaisePropertyChangedAuto(); OnSelectedParametersTableChanged(); }
+ }
+
+ private Job _activeJob;
+ /// <summary>
+ /// Gets or sets the selected machine job.
+ /// </summary>
+ public Job ActiveJob
+ {
+ get { return _activeJob; }
+ set
+ {
+ _activeJob = value;
+ RaisePropertyChangedAuto();
+ OnActiveJobChanged();
+ }
+ }
+
+ private Job _selectedMachineJob;
+ /// <summary>
+ /// Gets or sets the selected machine job.
+ /// </summary>
+ public Job SelectedMachineJob
+ {
+ get { return _selectedMachineJob; }
+ set { _selectedMachineJob = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ObservableCollection<Job> _selectedJobs;
+ /// <summary>
+ /// Gets or sets the selected jobs.
+ /// </summary>
+ public ObservableCollection<Job> SelectedJobs
+ {
+ get { return _selectedJobs; }
+ set { _selectedJobs = value; RaisePropertyChangedAuto(); }
+ }
+
+ private Segment _selectedSegment;
+ /// <summary>
+ /// Gets or sets the job selected segment.
+ /// </summary>
+ public Segment SelectedSegment
+ {
+ get { return _selectedSegment; }
+ set { _selectedSegment = value; RaisePropertyChangedAuto(); OnSelectedSegmentChanged(); }
+ }
+
+ private ObservableCollection<Segment> _selectedSegments;
+ /// <summary>
+ /// Gets or sets the selected segments.
+ /// </summary>
+ public ObservableCollection<Segment> SelectedSegments
+ {
+ get { return _selectedSegments; }
+ set { _selectedSegments = value; RaisePropertyChangedAuto(); }
+ }
+
+ private BrushStop _selectedBrushStop;
+ /// <summary>
+ /// Gets or sets the selected segment selected brush stop.
+ /// </summary>
+ public BrushStop SelectedBrushStop
+ {
+ get { return _selectedBrushStop; }
+ set { _selectedBrushStop = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ObservableCollection<BrushStop> _selectedBrushStops;
+ /// <summary>
+ /// Gets or sets the selected brush stops.
+ /// </summary>
+ public ObservableCollection<BrushStop> SelectedBrushStops
+ {
+ get { return _selectedBrushStops; }
+ set { _selectedBrushStops = value; RaisePropertyChangedAuto(); }
+ }
+
+ private Rml _selectedRML;
+ /// <summary>
+ /// Gets or sets the selected RML.
+ /// </summary>
+ public Rml SelectedRML
+ {
+ get { return _selectedRML; }
+ set
+ {
+ _selectedRML = value;
+ InvalidateLiquidFactorsAndProcessTables();
+ RaisePropertyChangedAuto();
+ InvalidateRelayCommands();
+ }
+ }
+
+ private bool _isSideBarOpened;
+ /// <summary>
+ /// Gets or sets a value indicating whether the configuration panels are opened.
+ /// </summary>
+ public bool IsSideBarOpened
+ {
+ get { return _isSideBarOpened; }
+ set { _isSideBarOpened = value; RaisePropertyChangedAuto(); }
+ }
+
+ private TimeSpan _estimatedDuration;
+ /// <summary>
+ /// Gets or sets the estimated duration for the selected job.
+ /// </summary>
+ public TimeSpan EstimatedDuration
+ {
+ get { return _estimatedDuration; }
+ set { _estimatedDuration = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isJobRunning;
+ /// <summary>
+ /// Gets or sets a value indicating whether a job is currently running.
+ /// </summary>
+ public bool IsJobRunning
+ {
+ get { return _isJobRunning; }
+ set { _isJobRunning = value; RaisePropertyChangedAuto(); }
+ }
+
+ private Job _runningJob;
+ /// <summary>
+ /// Gets or sets the currently running job.
+ /// </summary>
+ public Job RunningJob
+ {
+ get { return _runningJob; }
+ set { _runningJob = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _runningJobProgress;
+ /// <summary>
+ /// Gets or sets the running job current progress.
+ /// </summary>
+ public double RunningJobProgress
+ {
+ get { return _runningJobProgress; }
+ set { _runningJobProgress = value; RaisePropertyChangedAuto(); }
+ }
+
+ private TimeSpan _runningJobRemainingTime;
+ /// <summary>
+ /// Gets or sets the job remaining time.
+ /// </summary>
+ public TimeSpan RunningJobRemainingTime
+ {
+ get { return _runningJobRemainingTime; }
+ set { _runningJobRemainingTime = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isJobCompleted;
+ /// <summary>
+ /// Gets or sets a value indicating whether the running job has completed successfully.
+ /// </summary>
+ public bool IsJobCompleted
+ {
+ get { return _isJobCompleted; }
+ set { _isJobCompleted = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isJobFailed;
+ /// <summary>
+ /// Gets or sets a value indicating whether the running job has failed.
+ /// </summary>
+ public bool IsJobFailed
+ {
+ get { return _isJobFailed; }
+ set { _isJobFailed = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _showJobStatus;
+ /// <summary>
+ /// Gets or sets a value indicating whether to show all the relevant job status areas.
+ /// </summary>
+ public bool ShowJobStatus
+ {
+ get { return _showJobStatus; }
+ set { _showJobStatus = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isJobCanceled;
+ /// <summary>
+ /// Gets or sets a value indicating whether the last running job was canceled.
+ /// </summary>
+ public bool IsJobCanceled
+ {
+ get { return _isJobCanceled; }
+ set { _isJobCanceled = value; RaisePropertyChangedAuto(); }
+ }
+
+ private IMachineOperator _machineOperator;
+ /// <summary>
+ /// Gets or sets the machine operator.
+ /// </summary>
+ public IMachineOperator MachineOperator
+ {
+ get { return _machineOperator; }
+ set { _machineOperator = value; RaisePropertyChangedAuto(); }
+ }
+
+ private IRealTimeGraph _fullScreenGraph;
+ /// <summary>
+ /// Gets or sets the full screen graph.
+ /// </summary>
+ public IRealTimeGraph FullScreenGraph
+ {
+ get { return _fullScreenGraph; }
+ set { _fullScreenGraph = value; RaisePropertyChangedAuto(); }
+ }
+
+ private List<Segment> _runningJobSegments;
+ /// <summary>
+ /// Gets or sets the running job segments.
+ /// </summary>
+ public List<Segment> RunningJobSegments
+ {
+ get { return _runningJobSegments; }
+ set { _runningJobSegments = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ICollectionView _jobsCollectionView;
+ /// <summary>
+ /// Gets or sets the jobs collection view.
+ /// </summary>
+ public ICollectionView JobsCollectionView
+ {
+ get { return _jobsCollectionView; }
+ set
+ {
+ _jobsCollectionView = value;
+ BindingOperations.EnableCollectionSynchronization(_jobsCollectionView, _syncLock);
+
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ private ICollectionView _segmentsCollectionView;
+ /// <summary>
+ /// Gets or sets the segments collection view.
+ /// </summary>
+ public ICollectionView SegmentsCollectionView
+ {
+ get { return _segmentsCollectionView; }
+ set
+ {
+ _segmentsCollectionView = value;
+ BindingOperations.EnableCollectionSynchronization(_segmentsCollectionView, _syncLock);
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ private ICollectionView _brushStopsCollectionView;
+ /// <summary>
+ /// Gets or sets the brush stops collection view.
+ /// </summary>
+ public ICollectionView BrushStopsCollectionView
+ {
+ get { return _brushStopsCollectionView; }
+ set
+ {
+ _brushStopsCollectionView = value;
+ BindingOperations.EnableCollectionSynchronization(_brushStopsCollectionView, _syncLock);
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ private String _jobFilter;
+ /// <summary>
+ /// Gets or sets the job filter.
+ /// </summary>
+ public String JobFilter
+ {
+ get { return _jobFilter; }
+ set { _jobFilter = value; RaisePropertyChangedAuto(); OnJobFilterChanged(); }
+ }
+
+ #endregion
+
+ #region Commands
+
+ /// <summary>
+ /// Gets or sets the edit machine command.
+ /// </summary>
+ public RelayCommand EditMachineCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the edit RML command.
+ /// </summary>
+ public RelayCommand EditRMLCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the toggle side bar command.
+ /// </summary>
+ public RelayCommand ToggleSideBarCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the save process parameters command.
+ /// </summary>
+ public RelayCommand SaveProcessParametersCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the save liquid factors command.
+ /// </summary>
+ public RelayCommand SaveLiquidFactorsCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the add segment command.
+ /// </summary>
+ public RelayCommand AddSegmentCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the remove segment command.
+ /// </summary>
+ public RelayCommand RemoveSegmentCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the add job command.
+ /// </summary>
+ public RelayCommand AddJobCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the remove job command.
+ /// </summary>
+ public RelayCommand RemoveJobCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the add brush stop command.
+ /// </summary>
+ public RelayCommand AddBrushStopCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the remove brush stop command.
+ /// </summary>
+ public RelayCommand RemoveBrushStopCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the save job command.
+ /// </summary>
+ public RelayCommand SaveJobCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the discard job command.
+ /// </summary>
+ public RelayCommand DiscardJobCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the start job command.
+ /// </summary>
+ public RelayCommand StartJobCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the stop job command.
+ /// </summary>
+ public RelayCommand StopJobCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the close job completion status command.
+ /// </summary>
+ public RelayCommand CloseJobCompletionStatusCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the load job command.
+ /// </summary>
+ public RelayCommand LoadJobCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the duplicate job command.
+ /// </summary>
+ public RelayCommand DuplicateJobCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the duplicate segment command.
+ /// </summary>
+ public RelayCommand DuplicateSegmentCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets the duplicate brush stop command.
+ /// </summary>
+ public RelayCommand DuplicateBrushStopCommand { get; set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MainViewVM"/> class.
+ /// </summary>
+ public MainViewVM(IMainView view) : base(view, true)
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MainViewVM"/> class.
+ /// </summary>
+ /// <param name="applicationManager">The application manager.</param>
+ /// <param name="notificationProvider">The notification provider.</param>
+ [PreferredConstructor]
+ public MainViewVM(IMainView view, IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, IAuthenticationProvider authentication) : this(view)
+ {
+ SelectedJobs = new ObservableCollection<Job>();
+
+ LogManager.Log("Initializing machine Db context...");
+ _machineDbContext = ObservablesContext.CreateDefault();
+
+ if (SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedMachineGuid != null)
+ {
+ LogManager.Log("Setting last selected machine from settings...");
+ SelectedMachine = _machineDbContext.Machines.SingleOrDefault(x => x.Guid == SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedMachineGuid);
+ }
+
+ if (SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedJobGuid != null && SelectedMachine != null)
+ {
+ LogManager.Log("Setting last selected job from settings...");
+ SelectedMachineJob = SelectedMachine.Jobs.SingleOrDefault(x => x.Guid == SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedJobGuid);
+ }
+
+
+ _authentication = authentication;
+
+ _notification = notificationProvider;
+ _navigation = navigation;
+ ApplicationManager = applicationManager;
+ VideoCaptureProvider = videoCaptureProvider;
+
+ LogManager.Log("Initializing relay commands...");
+
+ //Initialize Commands...
+ EditMachineCommand = new RelayCommand(EditMachine, () => SelectedMachine != null);
+ EditRMLCommand = new RelayCommand(EditRML, () => SelectedRML != null);
+ ToggleSideBarCommand = new RelayCommand(() => IsSideBarOpened = !IsSideBarOpened);
+ SaveProcessParametersCommand = new RelayCommand(SaveProcessParameters, () => SelectedRML != null && SelectedRML.ProcessParametersTablesGroups.Count > 0);
+ SaveLiquidFactorsCommand = new RelayCommand(SaveLiquidFactors, () => SelectedRML != null);
+ AddSegmentCommand = new RelayCommand(AddSegment, () => ActiveJob != null);
+ RemoveSegmentCommand = new RelayCommand(RemoveSelectedSegments, () => SelectedSegment != null);
+ AddJobCommand = new RelayCommand(AddJob, () => SelectedMachine != null);
+ RemoveJobCommand = new RelayCommand(RemoveSelectedJobs, () => SelectedMachineJob != null);
+ AddBrushStopCommand = new RelayCommand(AddBrushStop, () => SelectedSegment != null);
+ RemoveBrushStopCommand = new RelayCommand(RemoveSelectedBrushStops, () => SelectedBrushStop != null);
+ SaveJobCommand = new RelayCommand(SaveActiveJob, () => SelectedMachine != null);
+ DiscardJobCommand = new RelayCommand(BackToJobs, () => SelectedMachine != null);
+ StartJobCommand = new RelayCommand(StartJob, () => ActiveJob != null && !IsJobRunning);
+ StopJobCommand = new RelayCommand(StopJob, () => IsJobRunning);
+ CloseJobCompletionStatusCommand = new RelayCommand(CloseJobCompletionStatusBar);
+ LoadJobCommand = new RelayCommand(LoadSelectedJob, () => SelectedMachineJob != null);
+ DuplicateJobCommand = new RelayCommand(DuplicateSelectedJobs, () => SelectedMachineJob != null);
+ DuplicateSegmentCommand = new RelayCommand(DuplicateSelectedSegments, () => SelectedSegment != null);
+ DuplicateBrushStopCommand = new RelayCommand(DuplicateSelectedBrushStops, () => SelectedBrushStop != null);
+
+ ApplicationManager.ConnectedMachineChanged += ApplicationManager_ConnectedMachineChanged;
+ }
+
+ #endregion
+
+ #region Event Handlers
+
+ /// <summary>
+ /// Handles the application manager connected machine changes event.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="machine">The machine.</param>
+ private void ApplicationManager_ConnectedMachineChanged(object sender, IExternalBridgeClient machine)
+ {
+ MachineOperator = machine;
+ }
+
+ /// <summary>
+ /// Handles the Saved event of the SelectedMachine.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
+ private void SelectedMachine_Saved(object sender, EventArgs e)
+ {
+ InvalidateLiquidFactorsAndProcessTables();
+ SelectedMachine.Reload(_machineDbContext);
+ }
+
+ /// <summary>
+ /// Handles the LengthChanged event of the SelectedJob.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
+ private void ActiveJob_LengthChanged(object sender, EventArgs e)
+ {
+ UpdateEstimatedDuration();
+ }
+
+ /// <summary>
+ /// Handles the DyeingSpeedMinInkUptakeChanged event of the SelectedProcessParametersTable.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
+ private void SelectedProcessParametersTable_DyeingSpeedMinInkUptakeChanged(object sender, EventArgs e)
+ {
+ if (SelectedSegment != null)
+ {
+ foreach (var liquidVolume in SelectedSegment.BrushStops.SelectMany(x => x.LiquidVolumes))
+ {
+ liquidVolume.Invalidate();
+ }
+ }
+
+ UpdateEstimatedDuration();
+ }
+
+ #endregion
+
+ #region Properties Changes
+
+ /// <summary>
+ /// Called when the selected parameters table has changed.
+ /// </summary>
+ protected virtual void OnSelectedParametersTableChanged()
+ {
+ if (SelectedProcessParametersTable != null)
+ {
+ LogManager.Log("Selected process parameters table changed.");
+ SelectedProcessParametersTable.DyeingSpeedMinInkUptakeChanged -= SelectedProcessParametersTable_DyeingSpeedMinInkUptakeChanged;
+ SelectedProcessParametersTable.DyeingSpeedMinInkUptakeChanged += SelectedProcessParametersTable_DyeingSpeedMinInkUptakeChanged;
+
+ SetSegmentBrushStopsLiquidVolumes(SelectedSegment);
+ UpdateEstimatedDuration();
+ }
+ }
+
+ /// <summary>
+ /// Called when the process parameters table group has been changed
+ /// </summary>
+ protected virtual void OnProcessParametersTableGroupChanged()
+ {
+ if (RmlProcessParametersTableGroup != null && RmlProcessParametersTableGroup.ProcessParametersTables.Count > 0)
+ {
+ LogManager.Log("Process parameters group changed...");
+ SelectedProcessParametersTable = RmlProcessParametersTableGroup.ProcessParametersTables.OrderBy(x => x.TableIndex).FirstOrDefault();
+
+ UpdateEstimatedDuration();
+ }
+ }
+
+ /// <summary>
+ /// Called when the selected segment has been changed
+ /// </summary>
+ protected virtual void OnSelectedSegmentChanged()
+ {
+ if (SelectedSegment != null)
+ {
+ LogManager.Log("Selected segment changed...");
+ SetSegmentBrushStopsLiquidVolumes(SelectedSegment);
+ SelectedBrushStop = SelectedSegment.BrushStops.FirstOrDefault();
+
+ BrushStopsCollectionView = CollectionViewSource.GetDefaultView(SelectedSegment.BrushStops);
+ BrushStopsCollectionView.SortDescriptions.Add(new SortDescription(nameof(BrushStop.StopIndex), ListSortDirection.Ascending));
+ }
+ }
+
+ /// <summary>
+ /// Called when the selected group history has been changed
+ /// </summary>
+ protected virtual void OnSelectedGroupHistoryChanged()
+ {
+ if (SelectedGroupHistory != null)
+ {
+ LogManager.Log(String.Format("Parameters group {0} selected from history.", SelectedGroupHistory.Name));
+ RmlProcessParametersTableGroup = SelectedGroupHistory.CloneGroup();
+ }
+ }
+
+ /// <summary>
+ /// Called when the machine has been changed
+ /// </summary>
+ protected virtual void OnSelectedMachineChanged()
+ {
+ if (SelectedMachine != null)
+ {
+ LogManager.Log(String.Format("Machine {0} changed.", SelectedMachine.SerialNumber));
+ ReloadMachine();
+ JobsCollectionView = CollectionViewSource.GetDefaultView(SelectedMachine.Jobs);
+ JobsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Job.LastUpdated), ListSortDirection.Descending));
+ }
+ }
+
+ /// <summary>
+ /// Called when the job filtering has changed.
+ /// </summary>
+ protected virtual void OnJobFilterChanged()
+ {
+ String filter = JobFilter.ToLower();
+
+ JobsCollectionView.Filter = (job) =>
+ {
+ Job j = job as Job;
+ return String.IsNullOrWhiteSpace(filter)
+ ||
+ j.Name.ToLower().Contains(filter) //Job name
+ ||
+ j.User.Contact.FirstName.ToLower().Contains(filter) // User first name
+ ||
+ j.Length.ToString().Contains(filter); //Job length
+ };
+ }
+
+ /// <summary>
+ /// Called when the active job has changed.
+ /// </summary>
+ protected virtual void OnActiveJobChanged()
+ {
+ if (ActiveJob != null)
+ {
+ LogManager.Log(String.Format("Active job {0} changed.", ActiveJob.Name));
+ SegmentsCollectionView = CollectionViewSource.GetDefaultView(ActiveJob.Segments);
+ SegmentsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Segment.SegmentIndex), ListSortDirection.Ascending));
+ }
+ }
+
+ #endregion
+
+ #region Drag & Drop
+
+ /// <summary>
+ /// Switch the segment position in the job.
+ /// </summary>
+ /// <param name="dragged">The dragged.</param>
+ /// <param name="dropped">The dropped.</param>
+ public void OnDropSegment(Segment dragged, Segment dropped)
+ {
+ LogManager.Log(String.Format("Segment {0} Dropped on segment {1}", dragged.SegmentIndex, dropped.SegmentIndex));
+
+ dragged.SegmentIndex = dropped.SegmentIndex;
+ dropped.SegmentIndex++;
+
+ int index = 1;
+
+ foreach (var segment in ActiveJob.Segments.OrderBy(x => x.SegmentIndex))
+ {
+ segment.SegmentIndex = index++;
+ }
+
+ SegmentsCollectionView.Refresh();
+ }
+
+ /// <summary>
+ /// Switch the brush stop position in the segment.
+ /// </summary>
+ /// <param name="dragged">The dragged stop.</param>
+ /// <param name="dropped">The dropped stop.</param>
+ public void OnDropBrushStop(BrushStop dragged, BrushStop dropped)
+ {
+ LogManager.Log(String.Format("BrushStop {0} Dropped on BrushStop {1}", dragged.StopIndex, dropped.StopIndex));
+
+ dragged.SetStopIndex(dropped.StopIndex);
+ dropped.SetStopIndex(dropped.StopIndex + 1);
+ ArrangeBrushStopsIndices();
+ }
+
+ #endregion
+
+ #region Running Job Management
+
+ /// <summary>
+ /// Closes the job completion status bar.
+ /// </summary>
+ private void CloseJobCompletionStatusBar()
+ {
+ LogManager.Log("Closing job completion status bar...");
+ _navigation.NavigateTo(DeveloperNavigationView.JobView);
+ IsJobCompleted = false;
+ IsJobFailed = false;
+ IsJobCanceled = false;
+ ShowJobStatus = false;
+ RunningJob = null;
+ }
+
+ /// <summary>
+ /// Stops the job.
+ /// </summary>
+ private void StopJob()
+ {
+ LogManager.Log("Stopping job...");
+ IsJobRunning = false;
+ IsJobCanceled = true;
+ _jobHandler.Cancel();
+ }
+
+ /// <summary>
+ /// Fails the job.
+ /// </summary>
+ private void SetJobFailed()
+ {
+ LogManager.Log("Setting job failed state...");
+ IsJobRunning = false;
+ IsJobFailed = true;
+ }
+
+ /// <summary>
+ /// Completes the job.
+ /// </summary>
+ private void SetJobCompleted()
+ {
+ LogManager.Log("Setting job completed state...");
+ IsJobRunning = false;
+ IsJobCompleted = true;
+ }
+
+ /// <summary>
+ /// Starts the job.
+ /// </summary>
+ private void StartJob()
+ {
+ LogManager.Log(String.Format("Starting job {0}...", ActiveJob.Name));
+ if (MachineOperator == null || MachineOperator.State != TransportComponentState.Connected)
+ {
+ _notification.ShowError("No machine connected. Could not execute the specified job.");
+ return;
+ }
+
+ if (SelectedProcessParametersTable == null)
+ {
+ _notification.ShowError("No process parameters table selected. Could not execute the specified job.");
+ return;
+ }
+
+ RunningJobRemainingTime = TimeSpan.Zero;
+ RunningJobProgress = 0;
+ IsJobFailed = false;
+ IsJobCanceled = false;
+ IsJobCompleted = false;
+ IsJobRunning = true;
+ ShowJobStatus = true;
+ RunningJob = ActiveJob;
+ _runningJobEstimatedDuration = EstimatedDuration;
+
+ RunningJobSegments = CreateRunningJobEffectiveSegments(RunningJob);
+
+ _navigation.NavigateTo(DeveloperNavigationView.RunningJobView);
+
+ LogManager.Log("Sending job to machine operator...");
+ _jobHandler = MachineOperator.Print(ActiveJob, SelectedProcessParametersTable);
+
+ _jobHandler.StatusReceived += (x, status) =>
+ {
+ RunningJobRemainingTime = _runningJobEstimatedDuration - TimeSpan.FromSeconds(RunningJobProgress / (SelectedProcessParametersTable.DyeingSpeed / 100d));
+ RunningJobProgress = status.Progress;
+
+ foreach (var segment in RunningJobSegments)
+ {
+ var previousSegmentsWithThis = RunningJobSegments.Where(s => RunningJobSegments.IndexOf(s) <= RunningJobSegments.IndexOf(segment)).ToList();
+ var segmentsDuration = TimeSpan.FromSeconds(previousSegmentsWithThis.Sum(s => s.Length) / (SelectedProcessParametersTable.DyeingSpeed / 100d));
+ var segmentDuration = TimeSpan.FromSeconds(segment.Length / (SelectedProcessParametersTable.DyeingSpeed / 100d));
+ TimeSpan remaining = segmentsDuration - TimeSpan.FromSeconds(RunningJobProgress / (SelectedProcessParametersTable.DyeingSpeed / 100d));
+ if (remaining >= TimeSpan.Zero)
+ {
+ segment.RemainingTime = remaining;
+ }
+ if (remaining < segmentDuration)
+ {
+ segment.Started = true;
+ }
+ if (remaining <= TimeSpan.Zero)
+ {
+ segment.Completed = true;
+ segment.Started = false;
+ }
+ }
+ };
+
+ _jobHandler.Failed += (x, ex) =>
+ {
+ LogManager.Log(ex, String.Format("Job {0} has failed.", RunningJob.Name));
+ SetJobFailed();
+
+ InvokeUI(() =>
+ {
+ _notification.ShowError("Job failed. " + ex.Message);
+ });
+ };
+
+ _jobHandler.Completed += (x, e) =>
+ {
+ LogManager.Log(String.Format("Job {0} has completed.", RunningJob.Name));
+ SetJobCompleted();
+ };
+
+ _jobHandler.Canceled += (x, y) =>
+ {
+ LogManager.Log(String.Format("Job {0} has been canceled.", RunningJob.Name));
+ //Finally Canceled..
+ };
+ }
+
+ /// <summary>
+ /// Creates the running job effective segments.
+ /// </summary>
+ /// <param name="job">The job.</param>
+ /// <returns></returns>
+ private List<Segment> CreateRunningJobEffectiveSegments(Job job)
+ {
+ LogManager.Log("Creating job effective segments...");
+
+ List<Segment> segments = new List<Segment>();
+ foreach (var s in job.Segments)
+ {
+ s.Completed = false;
+ s.Started = false;
+ segments.Add(s);
+
+ if (job.EnableInterSegment && job.Segments.IndexOf(s) != job.Segments.Count - 1)
+ {
+ segments.Add(new Segment()
+ {
+ Length = job.InterSegmentLength,
+ BrushStops = new System.Collections.ObjectModel.ObservableCollection<BrushStop>()
+ {
+ new BrushStop()
+ {
+ Color = Colors.White,
+ }
+ },
+ Started = false,
+ Completed = false
+ });
+ }
+ }
+
+ return segments;
+ }
+
+ #endregion
+
+ #region RML
+
+ /// <summary>
+ /// Saves the liquid factors.
+ /// </summary>
+ private async void SaveLiquidFactors()
+ {
+ if (SelectedRML != null)
+ {
+ using (_notification.PushTaskItem("Saving Liquid Factors..."))
+ {
+ LogManager.Log(String.Format("Saving liquid factors for RML {0}...", SelectedRML.Name));
+ await SelectedRML.SaveAsync(_activeJobDbContext);
+ InvalidateLiquidFactorsAndProcessTables();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Navigates to the DB Module in order to edit the selected RML.
+ /// </summary>
+ private void EditRML()
+ {
+ LogManager.Log(String.Format("Requesting DB module for RML {0} editing...", SelectedRML.Name));
+ ApplicationManager.RequestModule("Data Base", SelectedRML);
+ }
+
+ /// <summary>
+ /// Saves the process parameters group.
+ /// </summary>
+ private async void SaveProcessParameters()
+ {
+ var response = _notification.ShowTextInput("Enter Group Name", "Group Name");
+
+ if (response == null) return;
+
+ using (_notification.PushTaskItem("Saving Parameters Group..."))
+ {
+ LogManager.Log(String.Format("Saving process parameters group under the name {0}...", response));
+ ProcessParametersTablesGroup group = new ProcessParametersTablesGroup();
+
+ List<ProcessParametersTable> tables = new List<ProcessParametersTable>();
+ foreach (var table in RmlProcessParametersTableGroup.ProcessParametersTables)
+ {
+ var newTable = table.CloneEntity();
+ newTable.ProcessParametersTablesGroup = group;
+ tables.Add(newTable);
+ }
+
+ group.Active = true;
+ group.ProcessParametersTables = tables.ToObservableCollection();
+ group.Rml = SelectedRML;
+ group.Name = response;
+ group.SaveDate = DateTime.UtcNow;
+
+ foreach (var g in SelectedRML.ProcessParametersTablesGroups)
+ {
+ g.Active = false;
+ }
+
+ SelectedRML.ProcessParametersTablesGroups.Add(group);
+ await SelectedRML.SaveAsync(_activeJobDbContext);
+
+ InvalidateLiquidFactorsAndProcessTables();
+ }
+ }
+
+ /// <summary>
+ /// Invalidates the liquid factors and process parameters tables.
+ /// </summary>
+ private void InvalidateLiquidFactorsAndProcessTables()
+ {
+ if (SelectedRML != null && SelectedMachine != null)
+ {
+ LogManager.Log("Invalidating liquid factors, process parameters and process group history...");
+ LiquidTypesRmls = SelectedMachine.Configuration.IdsPacks.OrderBy(x => x.PackIndex).Select(x => x.LiquidType).SelectMany(x => x.LiquidTypesRmls).Where(x => x.Rml.Guid == SelectedRML.Guid).ToList();
+ RmlProcessParametersTableGroup = SelectedRML.ProcessParametersTablesGroups.ToList().SingleOrDefault(x => x.Active);
+
+ var selectedHistory = RmlProcessParametersTableGroup;
+
+ if (RmlProcessParametersTableGroup != null)
+ {
+ RmlProcessParametersTableGroup = RmlProcessParametersTableGroup.CloneGroup();
+ RmlProcessParametersTableGroup.ProcessParametersTables = RmlProcessParametersTableGroup.ProcessParametersTables.OrderBy(x => x.TableIndex).ToObservableCollection();
+ }
+
+ GroupsHistory = SelectedRML.ProcessParametersTablesGroups.OrderByDescending(x => x.SaveDate).OrderBy(x => !x.Active).ToObservableCollection();
+
+ _selectedGroupHistory = selectedHistory;
+
+ RaisePropertyChangedAuto(nameof(SelectedGroupHistory));
+ }
+ }
+
+ #endregion
+
+ #region Active Job Management
+
+ /// <summary>
+ /// Loads the selected job.
+ /// </summary>
+ private void LoadSelectedJob()
+ {
+ if (SelectedMachineJob != null)
+ {
+ using (_notification.PushTaskItem("Loading job details..."))
+ {
+ LogManager.Log(String.Format("Loading job {0}...", SelectedMachineJob.Name));
+ SelectedSegments = new ObservableCollection<Segment>();
+ SelectedBrushStops = new ObservableCollection<BrushStop>();
+ SelectedRML = null;
+ SelectedSegment = null;
+ SelectedGroupHistory = null;
+ SelectedBrushStop = null;
+ SelectedProcessParametersTable = null;
+ RmlProcessParametersTableGroup = null;
+
+
+ _blockInvalidateCommands = false;
+
+ LogManager.Log("Creating active job DB context...");
+ _activeJobDbContext = ObservablesContext.CreateDefault();
+ _activeJobDbContext.Configuration.LazyLoadingEnabled = true;
+
+ LogManager.Log("Initializing available color spaces, RMLs & Winding methods...");
+ ColorSpaces = _activeJobDbContext.ColorSpaces.ToObservableCollection();
+ Rmls = _activeJobDbContext.Rmls.ToObservableCollection();
+ WindingMethods = _activeJobDbContext.WindingMethods.ToObservableCollection();
+
+ LogManager.Log("Setting active job...");
+ _activeJob = _activeJobDbContext.Jobs.SingleOrDefault(x => x.Guid == SelectedMachineJob.Guid);
+
+ _selectedRML = ActiveJob.Rml;
+
+ LogManager.Log("Setting selected segment...");
+ _selectedSegment = ActiveJob.Segments.FirstOrDefault();
+
+ ActiveJob.LengthChanged -= ActiveJob_LengthChanged;
+ ActiveJob.LengthChanged += ActiveJob_LengthChanged;
+
+ ActiveJob = _activeJob;
+
+ SelectedRML = _selectedRML;
+ SelectedSegment = _selectedSegment;
+
+ UpdateEstimatedDuration();
+
+ _blockInvalidateCommands = false;
+ InvalidateRelayCommands();
+
+ _navigation.NavigateTo(DeveloperNavigationView.JobView);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Saves the active job.
+ /// </summary>
+ private async void SaveActiveJob()
+ {
+ if (ActiveJob != null)
+ {
+ using (_notification.PushTaskItem("Saving job details..."))
+ {
+ LogManager.Log(String.Format("Saving the active job {0}...", ActiveJob.Name));
+ ActiveJob.LastUpdated = DateTime.UtcNow;
+ ActiveJob.Rml = SelectedRML;
+
+ await ActiveJob.SaveAsync(_activeJobDbContext);
+ ReloadMachine();
+ SelectedMachineJob = SelectedMachine.Jobs.SingleOrDefault(x => x.Guid == ActiveJob.Guid);
+ }
+ }
+ }
+
+ private void BackToJobs()
+ {
+ LogManager.Log("User request for 'back to jobs'...");
+ LogManager.Log("Comparing active job with selected job...");
+
+ bool jobModified = !ActiveJob.CompareUsingJson(SelectedMachineJob);
+
+ if (jobModified)
+ {
+ LogManager.Log("Selected job has been modified. Invoking confirmation dialog...");
+ if (_notification.ShowQuestion("This will discard the current job changes. Are you sure?"))
+ {
+ LogManager.Log("Disposing active job db context...");
+ _activeJobDbContext.Dispose();
+ _navigation.NavigateTo(DeveloperNavigationView.MachineJobSelectionView);
+ }
+ }
+ else
+ {
+ LogManager.Log("Disposing active job db context...");
+ _activeJobDbContext.Dispose();
+ _navigation.NavigateTo(DeveloperNavigationView.MachineJobSelectionView);
+ }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private void ReloadMachine()
+ {
+ LogManager.Log("Reloading selected machine...");
+ _machineDbContext.Dispose();
+ _machineDbContext = ObservablesContext.CreateDefault();
+ _machineDbContext.Configuration.LazyLoadingEnabled = true;
+ String machineGuid = _selectedMachine.Guid;
+ Machines = _machineDbContext.Machines.ToObservableCollection();
+ _selectedMachine = Machines.SingleOrDefault(x => x.Guid == machineGuid);
+ RaisePropertyChanged(nameof(SelectedMachine));
+
+ JobsCollectionView = CollectionViewSource.GetDefaultView(SelectedMachine.Jobs);
+ JobsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Job.LastUpdated), ListSortDirection.Descending));
+ }
+
+ private void UpdateEstimatedDuration()
+ {
+ if (ActiveJob != null && SelectedProcessParametersTable != null && SelectedProcessParametersTable.DyeingSpeed > 0)
+ {
+ EstimatedDuration = TimeSpan.FromSeconds(ActiveJob.Length / (SelectedProcessParametersTable.DyeingSpeed / 100d));
+ }
+ }
+
+ private void SetSegmentBrushStopsLiquidVolumes(Segment segment)
+ {
+ if (!DesignMode && segment != null)
+ {
+ LogManager.Log("Setting segment brush stops liquid volumes...");
+ foreach (var stop in segment.BrushStops)
+ {
+ stop.SetLiquidVolumes(SelectedMachine.Configuration, SelectedRML, SelectedProcessParametersTable);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Navigates to the Machine Designer Module in order to edit the selected machine.
+ /// </summary>
+ private void EditMachine()
+ {
+ LogManager.Log(String.Format("Requesting machine designer module for machine {0} editing...", SelectedMachine.SerialNumber));
+ ApplicationManager.RequestModule("Machine Designer", SelectedMachine);
+ }
+
+ #endregion
+
+ #region Add / Remove / Duplicate Jobs, Segments & Brush Stops
+
+ /// <summary>
+ /// Arranges the segments indices.
+ /// </summary>
+ private void ArrangeSegmentsIndices()
+ {
+ int index = 1;
+
+ foreach (var segment in ActiveJob.Segments.OrderBy(x => x.SegmentIndex))
+ {
+ segment.SegmentIndex = index++;
+ }
+
+ SegmentsCollectionView.Refresh();
+ }
+
+ /// <summary>
+ /// Arranges the brush stops indices.
+ /// </summary>
+ private void ArrangeBrushStopsIndices()
+ {
+ int index = 0;
+
+ foreach (var stop in SelectedSegment.BrushStops.OrderBy(x => x.StopIndex))
+ {
+ stop.SetStopIndex(index++);
+ }
+
+ if (SelectedSegment.BrushStops.Count > 1)
+ {
+ SelectedSegment.BrushStops.OrderBy(x => x.StopIndex).First().OffsetPercent = 0;
+ SelectedSegment.BrushStops.OrderBy(x => x.StopIndex).Last().OffsetPercent = 100;
+ }
+
+ foreach (var stop in SelectedSegment.BrushStops.OrderBy(x => x.StopIndex))
+ {
+ stop.RaiseStopIndex();
+ stop.RaiseOffsetChanged();
+ }
+
+ BrushStopsCollectionView.Refresh();
+ }
+
+ /// <summary>
+ /// Removes the selected segments.
+ /// </summary>
+ private void RemoveSelectedSegments()
+ {
+ if (ActiveJob != null && SelectedSegment != null)
+ {
+ if (_notification.ShowQuestion("Are you sure you want to delete the selected segments?"))
+ {
+ LogManager.Log(String.Format("Removing {0} segments...", SelectedSegments.Count));
+
+ SelectedSegments.ToList().ForEach(x =>
+ {
+ ActiveJob.Segments.Remove(x);
+ x.DefferedDelete(_activeJobDbContext);
+ });
+
+ ArrangeSegmentsIndices();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds a new segment.
+ /// </summary>
+ private void AddSegment()
+ {
+ if (ActiveJob != null)
+ {
+ LogManager.LogFormat("Adding new segment to job {0}...", ActiveJob.Name);
+ Segment seg = new Segment();
+ seg.Name = "Untitled Segment";
+ seg.Length = 10;
+
+ if (ActiveJob.Segments.Count > 0)
+ {
+ seg.SegmentIndex = ActiveJob.Segments.Max(x => x.SegmentIndex) + 1;
+ }
+ else
+ {
+ seg.SegmentIndex = 1;
+ }
+ ActiveJob.Segments.Add(seg);
+ SelectedSegment = seg;
+ AddBrushStop();
+ ArrangeSegmentsIndices();
+ }
+ }
+
+ /// <summary>
+ /// Removes the selected jobs.
+ /// </summary>
+ private async void RemoveSelectedJobs()
+ {
+ if (SelectedMachine != null && SelectedMachineJob != null)
+ {
+ if (_notification.ShowQuestion("Are you sure you want to delete the selected jobs?"))
+ {
+ LogManager.Log(String.Format("Removing {0} jobs...", SelectedJobs.Count));
+ SelectedJobs.ToList().ForEach(x =>
+ {
+ SelectedMachine.Jobs.Remove(x);
+ x.DefferedDelete(_machineDbContext);
+ });
+
+ using (_notification.PushTaskItem("Removing selected jobs..."))
+ {
+ LogManager.Log("Saving selected machine to database...");
+ await SelectedMachine.SaveAsync(_machineDbContext);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds a new job to the selected machine.
+ /// </summary>
+ private async void AddJob()
+ {
+ if (SelectedMachine != null)
+ {
+ String jobName = _notification.ShowTextInput("Please provide a job name", "Name");
+
+ if (!String.IsNullOrWhiteSpace(jobName))
+ {
+ LogManager.Log(String.Format("Adding new job {0}...", jobName));
+
+ Job newJob = new Job();
+ newJob.Name = jobName;
+ newJob.CreationDate = DateTime.UtcNow;
+ newJob.User = _authentication.CurrentUser;
+ newJob.Rml = _machineDbContext.Rmls.FirstOrDefault();
+ newJob.WindingMethod = _machineDbContext.WindingMethods.FirstOrDefault();
+ newJob.Machine = SelectedMachine;
+
+ SelectedMachine.Jobs.Add(newJob);
+ LogManager.Log("Saving selected machine to database...");
+ await SelectedMachine.SaveAsync(_machineDbContext);
+ SelectedMachineJob = newJob;
+ LoadSelectedJob();
+ AddSegment();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Removes the selected brush stop.
+ /// </summary>
+ private void RemoveSelectedBrushStops()
+ {
+ if (SelectedBrushStop != null && SelectedSegment != null)
+ {
+ if (_notification.ShowQuestion("Are you sure you want to delete the selected colors?"))
+ {
+ LogManager.Log(String.Format("Removing {0} brush stops...", SelectedBrushStops.Count));
+
+ SelectedBrushStops.ToList().ForEach(x =>
+ {
+ SelectedSegment.BrushStops.Remove(x);
+ x.DefferedDelete(_activeJobDbContext);
+ });
+
+ ArrangeBrushStopsIndices();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds a new brush stop to the selected segment.
+ /// </summary>
+ private void AddBrushStop()
+ {
+ if (SelectedSegment != null)
+ {
+ LogManager.LogFormat("Adding new brush stop to segment...", SelectedSegment.SegmentIndex.ToString());
+
+ var stop = new BrushStop();
+
+ if (SelectedSegment.BrushStops.Count > 0)
+ {
+ stop.StopIndex = SelectedSegment.BrushStops.Max(x => x.StopIndex) + 1;
+ }
+ else
+ {
+ stop.StopIndex = 0;
+ }
+
+ stop.OffsetPercent = 100;
+ stop.Segment = SelectedSegment;
+ stop.ColorSpace = _activeJobDbContext.ColorSpaces.FirstOrDefault();
+ stop.Color = Colors.Black;
+ stop.SetLiquidVolumes(SelectedMachine.Configuration, SelectedRML, SelectedProcessParametersTable);
+ SelectedSegment.BrushStops.Add(stop);
+ SelectedSegment.BrushStops.ToList().ForEach(x => x.RaiseOffsetChanged());
+ ArrangeBrushStopsIndices();
+ }
+ }
+
+ /// <summary>
+ /// Duplicates the selected brush stops.
+ /// </summary>
+ private void DuplicateSelectedBrushStops()
+ {
+ LogManager.LogFormat("Duplicating {0} brush stops...", SelectedBrushStops.Count);
+
+ foreach (var stop in SelectedBrushStops.OrderBy(x => x.StopIndex))
+ {
+ var cloned = stop.Clone();
+ cloned.StopIndex = SelectedSegment.BrushStops.Max(x => x.StopIndex) + 1;
+ SelectedSegment.BrushStops.Add(cloned);
+ }
+
+ ArrangeBrushStopsIndices();
+ }
+
+ /// <summary>
+ /// Duplicates the selected segments.
+ /// </summary>
+ private void DuplicateSelectedSegments()
+ {
+ LogManager.LogFormat("Duplicating {0} segments...", SelectedSegments.Count);
+
+ foreach (var segment in SelectedSegments.OrderBy(x => x.SegmentIndex))
+ {
+ var cloned = segment.Clone();
+ cloned.SegmentIndex = ActiveJob.Segments.Max(x => x.SegmentIndex) + 1;
+ ActiveJob.Segments.Add(cloned);
+ }
+
+ ArrangeSegmentsIndices();
+ }
+
+ /// <summary>
+ /// Duplicates the selected jobs.
+ /// </summary>
+ private async void DuplicateSelectedJobs()
+ {
+ if (SelectedMachineJob != null)
+ {
+ using (_notification.PushTaskItem("Cloning selected jobs..."))
+ {
+ LogManager.LogFormat("Duplicating {0} jobs...", SelectedJobs.Count);
+
+ int index = SelectedMachine.Jobs.Max(x => x.JobIndex);
+
+ foreach (var job in SelectedJobs)
+ {
+ var cloned = job.Clone();
+ cloned.JobIndex = ++index;
+ SelectedMachine.Jobs.Add(cloned);
+ }
+
+ LogManager.Log("Saving selected machine to database...");
+ await SelectedMachine.SaveAsync(_machineDbContext);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Override Methods
+
+ protected override void RaisePropertyChangedAuto([CallerMemberName] string caller = null)
+ {
+ base.RaisePropertyChangedAuto(caller);
+
+ if (!_blockInvalidateCommands)
+ {
+ InvalidateRelayCommands();
+ }
+ }
+
+ #endregion
+
+ #region IShutdownRequestBlocker
+
+ public Task<bool> OnShutdownRequest()
+ {
+ if (IsJobRunning)
+ {
+ InvokeUI(() =>
+ {
+ _notification.ShowWarning("Please stop the currently running job before closing the developer module.");
+ });
+
+ return Task.FromResult(false);
+ }
+
+ return Task.FromResult(true);
+ }
+
+ #endregion
+
+ #region IShutdownListener
+
+ public void OnShuttingDown()
+ {
+ SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedMachineGuid = SelectedMachine != null ? SelectedMachine.Guid : null;
+ SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedJobGuid = SelectedMachineJob != null ? SelectedMachineJob.Guid : null;
+ }
+
+ #endregion
+
+ #region IMainView
+
+ protected override void OnViewAttached()
+ {
+ base.OnViewAttached();
+ }
+
+ #endregion
+ }
+}