using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Data; using Tango.BL; using Tango.BL.Entities; using Tango.BL.Enumerations; using Tango.Core.Commands; using Tango.Core.DI; using Tango.DragAndDrop; using Tango.PPC.Common; using Tango.PPC.Common.Messages; using Tango.PPC.Jobs.Dialogs; using Tango.PPC.Jobs.Messages; using Tango.PPC.Jobs.Views; using System.Data.Entity; using Tango.BL.Builders; using Tango.PPC.Jobs.NavigationObjects; using Tango.PPC.Storage; using Tango.Explorer; using System.IO; using Google.Protobuf; using Tango.PMR.Exports; using Tango.Settings; using Tango.Integration.ExternalBridge; using System.Windows.Media; using Tango.PMR.TCC; using Tango.Pulse; using System.Windows.Media.Imaging; using Tango.Touch.Components; using Tango.PPC.Jobs.ViewContracts; using Tango.Core.ExtensionMethods; using Tango.PPC.Common.Synchronization; using Tango.PPC.Jobs.NotificationItems; using Tango.PPC.Storage.Models; using Tango.BL.Helpers; using Tango.ColorConversion; namespace Tango.PPC.Jobs.ViewModels { /// /// Represents the jobs list view model. /// /// public class JobsViewVM : PPCViewModel { private ObservablesContext _db; //Holds the db context for the job list. private ObservableCollection _catalogs; //Holds the available color catalogs for the site. private ObservableCollection _rmls; //Holds the available RML for the site. private List _colorSpaces; //Holds the available color spaces. private bool _isJobsSynchronizationNotificationActive; public enum JobsCategory { Draft, History } #region Properties private ObservableCollection _jobs; /// /// Gets or sets the collection of jobs. /// public ObservableCollection Jobs { get { return _jobs; } set { _jobs = value; RaisePropertyChangedAuto(); } } private ICollectionView _draftJobsCollectionView; /// /// Gets or sets the jobs collection view. /// public ICollectionView DraftJobsCollectionView { get { return _draftJobsCollectionView; } set { _draftJobsCollectionView = value; RaisePropertyChangedAuto(); } } private ICollectionView _historyJobsCollectionView; /// /// Gets or sets the jobs collection view. /// public ICollectionView HistoryJobsCollectionView { get { return _historyJobsCollectionView; } set { _historyJobsCollectionView = value; RaisePropertyChangedAuto(); } } private ObservableCollection _selectedJobs; /// /// Gets or sets the selected jobs. /// public ObservableCollection SelectedJobs { get { return _selectedJobs; } set { _selectedJobs = value; RaisePropertyChangedAuto(); } } private bool _isLoadingJobs; /// /// Gets or sets a value indicating whether this instance is loading jobs. /// public bool IsLoadingJobs { get { return _isLoadingJobs; } set { _isLoadingJobs = value; RaisePropertyChangedAuto(); } } private bool _isMultiSelecting; /// /// Gets or sets a value indicating whether this the jobs list is in multi select mode. /// public bool IsMultiSelecting { get { return _isMultiSelecting; } set { _isMultiSelecting = value; RaisePropertyChangedAuto(); } } private int _selectedCategoryIndex; /// /// Gets or sets the index of the selected category. /// public int SelectedCategoryIndex { get { return _selectedCategoryIndex; } set { _selectedCategoryIndex = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(SelectedCategory)); } } /// /// Gets or sets the selected category. /// public JobsCategory SelectedCategory { get { return (JobsCategory)SelectedCategoryIndex; } set { if (SelectedCategoryIndex != value.ToInt32()) { SelectedCategoryIndex = value.ToInt32(); Filter = null; } } } private String _filter; /// /// Gets or sets the search filter. /// public String Filter { get { return _filter; } set { _filter = value; RaisePropertyChangedAuto(); OnFilterChanged(); } } private ICollectionFilter _collectionFilter; public ICollectionFilter CollectionFilter { get { return _collectionFilter; } set { _collectionFilter = value; RaisePropertyChangedAuto(); } } #endregion #region Commands /// /// Gets or sets the job selected command. /// public RelayCommand JobSelectedCommand { get; set; } /// /// Gets or sets the job drag and drop command. /// public RelayCommand JobDragedDroppedCommand { get; set; } /// /// Gets or sets the clear selection command. /// public RelayCommand ClearSelectionCommand { get; set; } /// /// Gets or sets the add job command. /// public RelayCommand AddJobCommand { get; set; } /// /// Gets or sets the delete jobs command. /// public RelayCommand DeleteJobsCommand { get; set; } /// /// Gets or sets the clone jobs command. /// public RelayCommand CloneJobsCommand { get; set; } /// /// Gets or sets the export job command. /// public RelayCommand ExportJobCommand { get; set; } #endregion #region Constructors /// /// Initializes a new instance of the class. /// public JobsViewVM() { Jobs = new ObservableCollection(); SelectedJobs = new ObservableCollection(); JobSelectedCommand = new RelayCommand((x) => SelectJob(x as Job)); JobDragedDroppedCommand = new RelayCommand((e) => { Job draggedJob = e.Draggable.DataContext as Job; Job droppedJob = e.Droppable.DataContext as Job; DragAndDropJob(draggedJob, droppedJob); }); ClearSelectionCommand = new RelayCommand(ClearSelection); AddJobCommand = new RelayCommand(() => AddNewJob()); DeleteJobsCommand = new RelayCommand(() => DeleteJobs(SelectedJobs)); CloneJobsCommand = new RelayCommand(() => CloneJobs(SelectedJobs)); ExportJobCommand = new RelayCommand(ExportJob); RegisterForMessage(HandleJobRemovedMessage); RegisterForMessage(HandleJobSavedMessage); RegisterForMessage((x) => Filter = null); CollectionFilter = new DefaultCollectionFilter(); CollectionFilter.RegisterFilter(item => { var job = item as Job; if (job != null) { if (String.IsNullOrEmpty(Filter)) { return true; } else { return (job.Name.ToLower().Contains(Filter.ToLower()) || (job.Customer != null && job.Customer.Name.ToLower().StartsWith(Filter.ToLower()))); } } else { return true; } }); } #endregion #region Drag & Drop /// /// Called when a job has been dragged and dropped into another job. /// /// The dragged job. /// The dropped job. private void DragAndDropJob(Job draggedJob, Job droppedJob) { LogManager.Log($"Job Drag & Drop '{draggedJob.Name}' => '{droppedJob.Name}'."); if (draggedJob.JobIndex > droppedJob.JobIndex) { draggedJob.JobIndex = droppedJob.JobIndex - 1; } else { draggedJob.JobIndex = droppedJob.JobIndex + 1; } int index = 1; foreach (var job in Jobs.OrderBy(x => x.JobIndex)) { job.JobIndex = index++; } DraftJobsCollectionView.Refresh(); } #endregion #region Job Selection & Loading /// /// Selects the job. /// /// The job. public async void SelectJob(Job job, bool directlyToEdit = false) { //if (!ApplicationManager.IsInTechnicianMode && job.ColorSpace != null && job.ColorSpace.Code == ColorSpaces.Volume.ToInt32()) //{ // await NotificationProvider.ShowError("The selected job is supported only in technician mode."); // return; //} LogManager.Log($"Job '{job.Name}' selected."); RaiseMessage(new JobSelectedMessage() { Job = job, Context = _db }); if (!directlyToEdit && MachineProvider.MachineOperator.CanPrint) { await NavigationManager.NavigateWithObject(new JobSummeryNavigationObject() { Context = _db, Job = job, }); } else { await NavigationManager.NavigateTo(nameof(JobView)); } } /// /// Loads the jobs from database. /// public void LoadJobs(Action onCompleted = null) { try { LogManager.Log("Loading machine jobs..."); Task.Factory.StartNew(() => { IsLoadingJobs = true; Thread.Sleep(500); _db = ObservablesContext.CreateDefault(); _colorSpaces = _db.ColorSpaces.ToList(); var jobs = new JobsCollectionBuilder(_db).Set(x => x.MachineGuid == MachineProvider.Machine.Guid).WithSegments().WithBrushStops().WithCustomer().WithColorSpace().Build(); InvokeUI(() => { Jobs = jobs; DraftJobsCollectionView = new ListCollectionView(Jobs); DraftJobsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Job.LastUpdated), ListSortDirection.Descending)); DraftJobsCollectionView.Filter = new Predicate(x => { var job = x as Job; return job.JobStatus == JobStatuses.Draft; }); HistoryJobsCollectionView = new ListCollectionView(Jobs); HistoryJobsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Job.LastUpdated), ListSortDirection.Descending)); HistoryJobsCollectionView.Filter = new Predicate(x => { var job = x as Job; return job.JobStatus != JobStatuses.Draft; }); IsLoadingJobs = false; LogManager.Log("Machine jobs loaded!"); onCompleted?.Invoke(); }); }); } catch (Exception ex) { LogManager.Log(ex); NotificationProvider.ShowError("An error occurred while trying to load the machine jobs."); } } /// /// Clears the job selection. /// public void ClearSelection() { SelectedJobs.Clear(); IsMultiSelecting = false; } /// /// Adds a new job. /// private async void AddNewJob(Color? colorProfile = null, TwnFile twnFile = null) { try { LogManager.Log("Adding new job..."); var settings = SettingsManager.Default.GetOrCreate(); var machine = MachineProvider.Machine; JobCreationViewVM vm = new JobCreationViewVM( Settings.SupportedJobTypes.Count > 0 ? Settings.SupportedJobTypes : Enum.GetValues(typeof(JobTypes)).Cast().ToList(), Enum.GetValues(typeof(ColorSpaces)).Cast().Where(x => x != ColorSpaces.CMYK).ToList() ); if (_catalogs.Count == 0) { vm.SupportedColorSpaces.Remove(ColorSpaces.Catalog); } CatalogSelectionViewVM catalogVM = new CatalogSelectionViewVM(_catalogs.ToList(), _catalogs.ToList().SingleOrDefault(x => x.Guid == settings.LastSelectedCatalogGuid)); if (settings.LastJobType != null) { vm.SelectedJobType = settings.LastJobType.Value; } else { vm.SelectedJobType = Settings.SupportedJobTypes.FirstOrDefault(); } if (settings.LastJobColorSpace != null) { vm.SelectedColorSpace = settings.LastJobColorSpace.Value.IsUserSpace() ? settings.LastJobColorSpace.Value : ColorSpaces.Catalog; } else { var space = Settings.SupportedColorSpaces.FirstOrDefault(); vm.SelectedColorSpace = space.IsUserSpace() ? space : ColorSpaces.Catalog; } if (colorProfile != null || twnFile != null) { vm.SupportedColorSpaces = new List() { ColorSpaces.RGB }; vm.SelectedColorSpace = vm.SupportedColorSpaces.First(); } if (twnFile != null) { vm.SupportedJobTypes = new List() { JobTypes.Embroidery }; vm.SelectedJobType = vm.SupportedJobTypes.First(); } if (twnFile == null) { if (Settings.SupportedJobTypes.Count != 1 || Settings.SupportedColorSpaces.Count != 1) { vm = await NotificationProvider.ShowDialog(vm); if (!vm.DialogResult) return; if (vm.SelectedColorSpace == ColorSpaces.Catalog) { if (catalogVM.SelectedCatalog == null) { catalogVM.SelectedCatalog = _catalogs.FirstOrDefault(); } if (_catalogs.Count == 0) { await NotificationProvider.ShowError("No color catalogs found. Please selected another color space."); return; } else if (_catalogs.Count > 1) { catalogVM = await NotificationProvider.ShowDialog(catalogVM); if (!catalogVM.DialogResult) { return; } } } } else { vm.SelectedJobType = Settings.SupportedJobTypes.First(); vm.SelectedColorSpace = Settings.SupportedColorSpaces.First(); } } settings.LastJobType = vm.SelectedJobType; settings.LastJobColorSpace = vm.SelectedColorSpace; if (vm.SelectedColorSpace == ColorSpaces.Catalog) { settings.LastSelectedCatalogGuid = catalogVM.SelectedCatalog.Guid; } settings.Save(); Job job = new Job(); job.LastUpdated = DateTime.UtcNow; job.JobSource = JobSource.Local; job.Name = "untitled"; job.NumberOfHeads = 1; if(BuildProvider.MachineType == MachineTypes.Eureka) { job.NumberOfUnits = 4; //job.NumberOfHeads = 4; } else { job.NumberOfUnits = 1; } job.SampleUnitsOrMeters = 1; job.CreationDate = DateTime.UtcNow; job.JobStatus = JobStatuses.Draft; job.JobType = vm.SelectedJobType; job.EnableLubrication = true; job.ColorSpaceGuid = Adapter.ColorSpaces.FirstOrDefault(x => x.Code == vm.SelectedColorSpace.ToInt32()).Guid; job.ColorSpace = _colorSpaces.SingleOrDefault(x => x.Guid == job.ColorSpaceGuid); job.MachineGuid = MachineProvider.Machine.Guid; job.UserGuid = null; job.RmlGuid = (Settings.DefaultRmlGuid != null && _rmls.Select(x => x.Guid).Contains(Settings.DefaultRmlGuid)) ? Settings.DefaultRmlGuid : _rmls.FirstOrDefault().Guid; job.WindingMethodGuid = Adapter.WindingMethods.FirstOrDefault().Guid; job.SpoolTypeGuid = Settings.SpoolTypeGuid != null ? Settings.SpoolTypeGuid : Adapter.SpoolTypes.FirstOrDefault(x => x.Code == (int)SpoolTypes.StandardSpool).Guid; if (vm.SelectedColorSpace == ColorSpaces.Catalog) { job.ColorCatalogGuid = catalogVM.SelectedCatalog.Guid; } if (Jobs.Count > 0) { job.JobIndex = Jobs.Max(x => x.JobIndex) + 1; } if (colorProfile == null) { var segment = job.AddSolidSegment(Settings.DefaultSegmentLength > 0 ? Settings.DefaultSegmentLength : 100); try { if (vm.SelectedColorSpace == ColorSpaces.Catalog) { segment.BrushStops[0].ColorCatalogGuid = catalogVM.SelectedCatalog.Guid; } } catch (Exception ex) { LogManager.Log(ex, $"Error setting first segment brush stop color catalog guide."); } } else { job.AddSolidSegment(colorProfile.Value, Settings.DefaultSegmentLength > 0 ? Settings.DefaultSegmentLength : 100); job.Name = $"SnapMatch {colorProfile.Value.R}, {colorProfile.Value.G}, {colorProfile.Value.B}"; } if (twnFile != null) { job.Name = twnFile.Name; job.NumberOfUnits = Math.Max(twnFile.NumberOfCopies, 1); job.EmbroideryFileName = twnFile.Name + "." + twnFile.EmbroideryFileFormat; job.EmbroideryFileData = twnFile.EmbroideryFile; job.EmbroideryJpeg = twnFile.ThumbnailData; job.Segments.Clear(); int index = 1; foreach (var segment in twnFile.Segments) { Segment s = new Segment(); s.Job = job; s.SegmentIndex = index++; s.Name = "Embroidery Segment"; s.Length = segment.Length / 100d; int sIndex = 1; foreach (var stop in segment.BrushStops) { BrushStop st = new BrushStop(); st.Segment = s; st.StopIndex = sIndex++; st.OffsetPercent = stop.Offset * 100d; st.Red = stop.R; st.Green = stop.G; st.Blue = stop.B; st.ColorSpaceGuid = job.ColorSpaceGuid; s.BrushStops.Add(st); } job.Segments.Add(s); } } _db.Jobs.Add(job); await _db.SaveChangesAsync(); Jobs.Add(job); LogManager.Log($"Job {job.Name} added successfully."); RaiseMessage(new JobSelectedMessage() { Job = job, Context = _db }); await Task.Delay(200); await NavigationManager.NavigateWithObject(new JobNavigationObject() { Job = job, Intent = JobNavigationIntent.NewJob }); } catch (Exception ex) { LogManager.Log(ex, "Error creating new job."); await NotificationProvider.ShowError("An error occurred while trying to add a new job."); } } /// /// Deletes the specified jobs from db. /// /// The jobs. private async void DeleteJobs(ObservableCollection jobs) { try { LogManager.Log($"Removing selected jobs:\n{jobs.Select(x => x.Name).ToList().ToJsonString()}"); if (await NotificationProvider.ShowQuestion("Are you sure you want to delete the selected jobs")) { foreach (var job in jobs) { await job.DeleteCascadeAsync(_db); Jobs.Remove(job); } await _db.SaveChangesAsync(); ClearSelection(); } } catch (Exception ex) { LogManager.Log(ex, "Error removing selected jobs."); await NotificationProvider.ShowError("An error occurred while trying to remove the selected jobs."); } } /// /// Clones the specified jobs. /// /// The jobs. private async void CloneJobs(ObservableCollection jobs) { try { LogManager.Log($"Cloning selected jobs:\n{jobs.Select(x => x.Name).ToList().ToJsonString()}"); int index = Jobs.Max(x => x.JobIndex); List clonedJobs = new List(); foreach (var job in SelectedJobs) { var cloned = job.Clone(); cloned.JobIndex = ++index; _db.Jobs.Add(cloned); clonedJobs.Add(cloned); } await _db.SaveChangesAsync(); foreach (var job in clonedJobs) { Jobs.Add(job); } ClearSelection(); } catch (Exception ex) { LogManager.Log(ex, "Error cloning selected jobs."); await NotificationProvider.ShowError("An error occurred while trying to clone the selected jobs."); } } /// /// Called when the search filter has been changed /// private void OnFilterChanged() { if (DraftJobsCollectionView != null && HistoryJobsCollectionView != null) { CollectionFilter.RaiseFilterChanged(); View.ScrollToTop(); } } #endregion #region Message Handling /// /// Handles the job removed message. /// /// The MSG. private void HandleJobRemovedMessage(JobRemovedMessage msg) { try { LogManager.Log("JobRemovedMessage message received, removing job from list..."); var job = Jobs.SingleOrDefault(x => x.Guid == msg.Job.Guid); Jobs.Remove(job); _db.Entry(job).State = System.Data.Entity.EntityState.Detached; } catch (Exception ex) { LogManager.Log(ex, "Could not remove job"); } } /// /// Handles the job saved message. /// /// The MSG. private void HandleJobSavedMessage(JobSavedMessage msg) { LogManager.Log("JobSavedMessage message received."); LoadJobs(); } #endregion #region Override Methods /// /// Called when the application has been started. /// public override void OnApplicationStarted() { LoadJobs(); ExternalBridgeService.ColorProfileRequest += ExternalBridgeService_ColorProfileRequest; } public async override void OnApplicationReady() { base.OnApplicationReady(); StorageProvider.RegisterFileHandler(ExplorerFileDefinition.Job.Extension, HandleJobFileLoaded); StorageProvider.RegisterFileHandler(ExplorerFileDefinition.ColorProfile.Extension, HandleColorProfileFileLoaded); StorageProvider.RegisterFileHandler(ExplorerFileDefinition.Pulse.Extension, HandlePulseFileLoaded); StorageProvider.RegisterFileHandler(ExplorerFileDefinition.CsvFile.Extension, HandleCsvJobFileLoaded); //Load catalogs. using (ObservablesContext db = ObservablesContext.CreateDefault()) { _catalogs = await new CatalogsCollectionBuilder(db).SetAll().ForSite(MachineProvider.Machine.SiteGuid).BuildAsync(); _rmls = await new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).BuildAsync(); } MachineDataSynchronizer.SynchronizationEnded += MachineDataSynchronizer_SynchronizationEnded; } public override void OnNavigatedTo() { base.OnNavigatedTo(); JobViewVM._start_printing_btn?.Pop(); Filter = null; } #endregion #region Job Export private async void ExportJob() { var selected_job = SelectedJobs.FirstOrDefault(); if (selected_job == null) return; var selectedJobs = SelectedJobs.ToList(); ClearSelection(); var result = await NavigationManager. NavigateForResult( new StorageNavigationRequest() { Intent = selectedJobs.Count == 1 ? StorageNavigationIntent.SaveFile : StorageNavigationIntent.SaveFiles, DefaultFileName = selected_job.Name, Filter = ExplorerFileDefinition.Job.Extension, Title = selectedJobs.Count == 1 ? "Save Job File" : "Save Job Files", }); if (result != null) { if (selectedJobs.Count == 1) { try { var jobFile = await selected_job.ToJobFile(); using (FileStream fs = new FileStream(result.Path + ExplorerFileDefinition.Job.Extension, FileMode.Create)) { jobFile.WriteTo(fs); } await NotificationProvider.ShowSuccess("Job saved successfully."); } catch (Exception ex) { LogManager.Log(ex, $"Error saving job {selected_job.Name} to file."); await NotificationProvider.ShowError($"An error occurred while trying to save the job.\n{ex.Message}"); } } else { foreach (var job in selectedJobs) { try { var jobFile = await job.ToJobFile(); using (FileStream fs = new FileStream(Path.Combine(result.Path, jobFile.Name.ToValidFileName()) + ExplorerFileDefinition.Job.Extension, FileMode.Create)) { jobFile.WriteTo(fs); } } catch (Exception ex) { LogManager.Log(ex, $"Error saving job {job.Name} to file."); await NotificationProvider.ShowError($"An error occurred while trying to save the job.\n{ex.Message}"); } } await NotificationProvider.ShowSuccess("Jobs saved successfully."); } } } #endregion #region Handle Job File Loading From Storage private async void HandleJobFileLoaded(List jobFiles) { var vm = await NotificationProvider.ShowDialog(); if (vm.DialogResult) { using (ObservablesContext jobContext = ObservablesContext.CreateDefault()) { foreach (var jobFile in jobFiles) { try { JobFile jFile = JobFile.Parser.ParseFrom(File.ReadAllBytes(jobFile.Path)); var job = await Job.FromJobFile(jFile, MachineProvider.Machine.Guid, null); job.JobSource = JobSource.Local; jobContext.Jobs.Add(job); await jobContext.SaveChangesAsync(); } catch (Exception ex) { LogManager.Log(ex, $"Error occurred while trying to import job from file {jobFile.Path}."); await NotificationProvider.ShowError($"An error occurred while trying to import the selected job file.\n{ex.Message}"); } } LoadJobs(() => { //Editing of a job is currently deprecated due to enabling multiple job imports. //if (vm.ImportAndEdit) //{ // var postJob = Jobs.SingleOrDefault(x => x.Guid == job.Guid); // if (postJob != null) // { // SelectJob(postJob, true); // } //} }); } } } #endregion #region Handle CSV Job File Loading From Storage private async void HandleCsvJobFileLoaded(List files) { //var item = files.FirstOrDefault(); //if (item == null) return; //var vm = new ImportCsvJobViewVM(); //vm.Name = Path.GetFileNameWithoutExtension(item.Name); //await vm.Init(); //await NotificationProvider.ShowDialog(vm); //if (vm.DialogResult && vm.SelectedRml != null) //{ // try // { // NotificationProvider.SetGlobalBusyMessage("Importing job from file..."); // using (ObservablesContext db = ObservablesContext.CreateDefault()) // { // var segments = await SegmentsCsvHelper.FromFile(item.Path, MachineProvider.Machine, db); // Job job = new Job(); // job.LastUpdated = DateTime.UtcNow; // job.JobSource = JobSource.Local; // job.Name = vm.Name; // job.NumberOfHeads = 1; // job.NumberOfUnits = 1; // job.SampleUnitsOrMeters = 1; // job.CreationDate = DateTime.UtcNow; // job.JobStatus = JobStatuses.Draft; // job.JobType = JobTypes.Knitting; // job.EnableLubrication = true; // job.MachineGuid = MachineProvider.Machine.Guid; // job.RmlGuid = vm.SelectedRml.Guid; // job.Machine = await new MachineBuilder(db).Set(job.MachineGuid).WithCats().WithConfiguration().BuildAsync(); // job.Rml = await new RmlBuilder(db).Set(job.RmlGuid).WithActiveParametersGroup().WithCAT(MachineProvider.Machine.Guid).WithCCT().WithGbdAndLub().WithLiquidFactors().BuildAsync(); // job.WindingMethodGuid = Adapter.WindingMethods.FirstOrDefault().Guid; // job.SpoolTypeGuid = Settings.SpoolTypeGuid != null ? Settings.SpoolTypeGuid : Adapter.SpoolTypes.FirstOrDefault().Guid; // foreach (var segment in segments) // { // segment.Job = job; // job.Segments.Add(segment); // } // IColorConverter converter = new DefaultColorConverter(); // foreach (var stop in segments.SelectMany(x => x.BrushStops.Where(y => y.BrushColorSpace == ColorSpaces.Volume))) // { // var output = converter.Convert(stop, false); // var suggestion = output.CreateSingleSuggestion(); // stop.Color = suggestion.Color; // } // db.Jobs.Add(job); // await db.SaveChangesAsync(); // LoadJobs(); // } // NotificationProvider.ReleaseGlobalBusyMessage(); // } // catch (Exception ex) // { // NotificationProvider.ReleaseGlobalBusyMessage(); // LogManager.Log(ex, "Error importing job from CSV."); // await NotificationProvider.ShowError($"Error importing job from csv file.\n{ex.FlattenMessage()}"); // } //} } #endregion #region Handle TCC File Loading From Storage private async void HandleColorProfileFileLoaded(List tccFiles) { var tccFile = tccFiles.FirstOrDefault(); try { DetectionColorFile tcc = DetectionColorFile.Parser.ParseFrom(File.ReadAllBytes(tccFile.Path)); var vm = await NotificationProvider.ShowDialog(new ImportColorProfileViewVM() { Color = Color.FromRgb( (byte)tcc.ProcessedColor.R, (byte)tcc.ProcessedColor.G, (byte)tcc.ProcessedColor.B), }); if (vm.DialogResult) { AddNewJob(vm.Color); } } catch (Exception ex) { LogManager.Log(ex, $"Error occurred while trying to import detection color from file {tccFile.Path}."); await NotificationProvider.ShowError($"An error occurred while trying to import the selected detection color.\n{ex.Message}"); } } #endregion #region Handle Pulse TWN Loading From Storage private async void HandlePulseFileLoaded(List twnFiles) { var twnFile = twnFiles.FirstOrDefault(); TwnFile twn = TwnFile.FromFile(twnFile.Path); BitmapSource preview = twn.Thumbnail.ToBitmapSource(); var vm = await NotificationProvider.ShowDialog(new ImportTwnFileViewVM() { Thumbnail = preview, }); if (vm.DialogResult) { AddNewJob(null, twn); } } #endregion #region Handle New Synchronized Jobs private void MachineDataSynchronizer_SynchronizationEnded(object sender, SynchronizationEndedEventArgs e) { if (e.NewChangedJobs > 0 && !_isJobsSynchronizationNotificationActive) { _isJobsSynchronizationNotificationActive = true; var item = NotificationProvider.PushNotification(); item.Pressed += (_, __) => { _isJobsSynchronizationNotificationActive = false; LoadJobs(() => { NotificationProvider.ShowSuccess("Your job list is now synchronized."); }); }; item.Closed += (_, __) => { _isJobsSynchronizationNotificationActive = false; }; } } #endregion #region Color Profile Request private void ExternalBridgeService_ColorProfileRequest(object sender, ColorProfileRequestEventArgs e) { InvokeUI(async () => { var vm = await NotificationProvider.ShowDialog(new ColorProfileReceivedViewVM() { Color = Color.FromRgb( (byte)e.Request.DetectionColor.R, (byte)e.Request.DetectionColor.G, (byte)e.Request.DetectionColor.B), }); if (vm.DialogResult) { e.Approve(); AddNewJob(vm.Color); } else { e.Decline(); } }); } #endregion } }