diff options
| author | Shlomo Hecht <shlomo@twine-s.com> | 2020-10-29 15:55:21 +0200 |
|---|---|---|
| committer | Shlomo Hecht <shlomo@twine-s.com> | 2020-10-29 15:55:21 +0200 |
| commit | 4b789f33eadfc5cc1d937a80ce03ea8425955ffe (patch) | |
| tree | 7dbbd0529a24f9ca064cab688a0d6d2b8b762ea1 /Software/Visual_Studio/MachineStudio/Modules | |
| parent | 8f3baa0d9097aa6ed800863a4680608e867c809a (diff) | |
| parent | 11fb700fcbc4627162a9c3f84b03b5016248bd97 (diff) | |
| download | Tango-4b789f33eadfc5cc1d937a80ce03ea8425955ffe.tar.gz Tango-4b789f33eadfc5cc1d937a80ce03ea8425955ffe.zip | |
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules')
43 files changed, 2112 insertions, 237 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/MachineStudio.Dispensers/Views/DispenserView.xaml b/Software/Visual_Studio/MachineStudio/Modules/MachineStudio.Dispensers/Views/DispenserView.xaml index 0a63e6423..e0f93df5a 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/MachineStudio.Dispensers/Views/DispenserView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/MachineStudio.Dispensers/Views/DispenserView.xaml @@ -51,9 +51,9 @@ <TextBox Text="{Binding ActiveDispenser.SerialNumber}"></TextBox> <TextBlock FontWeight="SemiBold">Dispenser Type:</TextBlock> - <ComboBox ItemsSource="{Binding DispenserTypes}" SelectedItem="{Binding ActiveDispenser.DispenserType}" DisplayMemberPath="Name"></ComboBox> + <ComboBox ItemsSource="{Binding DispenserTypes}" SelectedItem="{Binding ActiveDispenser.DispenserType}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}" ></ComboBox> - <TextBlock FontWeight="SemiBold">Nanoliter / Pulse:</TextBlock> + <TextBlock FontWeight="SemiBold">Nanoliter / Pulse:</TextBlock> <mahapps:NumericUpDown HorizontalContentAlignment="Left" HasDecimals="True" BorderThickness="0 0 0 1" Background="Transparent" Minimum="0" Maximum="5" Value="{Binding ActiveDispenser.NlPerPulse}"></mahapps:NumericUpDown> <TextBlock FontWeight="SemiBold">Part Number:</TextBlock> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml index e2d65d7a3..146735eaa 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml @@ -4,14 +4,14 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" - xmlns:local="clr-namespace:Tango.MachineStudio.ActionLogs.Views" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:sharedConverters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:vm="clr-namespace:Tango.MachineStudio.ActionLogs.ViewModels" xmlns:global="clr-namespace:Tango.MachineStudio.ActionLogs" - xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf" xmlns:diff="clr-namespace:Tango.BL.ValueObjects;assembly=Tango.BL" + xmlns:local="clr-namespace:Tango.MachineStudio.ActionLogs.Views" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> <UserControl.Resources> @@ -60,7 +60,7 @@ </StackPanel> <DockPanel Margin="50 0 0 0" > <TextBlock DockPanel.Dock="Top" Text="Action Log Type:" VerticalAlignment="Center" FontSize="10"></TextBlock> - <ToggleButton Width="200" Margin="0 5 0 0" x:Name="selectActionsButton"> + <ToggleButton Width="200" Margin="0 5 0 0" x:Name="selectActionsButton" > <ToggleButton.Template> <ControlTemplate> <Grid> @@ -75,21 +75,16 @@ </TextBlock> </DockPanel> </Border> - <Popup StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }" > - <Border Padding="5" Background="{DynamicResource ComboBox.Floating.Background}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}"> - <ScrollViewer MaxHeight="600" Background="{DynamicResource ComboBox.Floating.Background}"> - <ItemsControl ItemsSource="{Binding SelectedActionLogTypes}" Foreground="{StaticResource MainWindow.Foreground}"> - <ItemsControl.ItemTemplate> - <DataTemplate> - <DockPanel Margin="2"> - <CheckBox VerticalAlignment="Center" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" > - <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data,Converter={StaticResource EnumToDescriptionConverter}}"></TextBlock> - </CheckBox> - </DockPanel> - </DataTemplate> - </ItemsControl.ItemTemplate> - </ItemsControl> - </ScrollViewer> + <Popup StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }" Style="{x:Null}"> + <Border Padding="5" MaxHeight="600" Background="{DynamicResource ComboBox.Floating.Background}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=ActualWidth}"> + <controls:AllSelectedCheckboxList Style="{StaticResource AllSelectedCheckBoxListStyle}" MaxHeight="600" ItemsSource="{Binding SelectedActionLogTypes}" Foreground="{StaticResource MainWindow.Foreground}" Background="{DynamicResource ComboBox.Floating.Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionMode="Multiple" AllSelected="True" FontSize="11" FontFamily="{StaticResource FontName}"> + <controls:AllSelectedCheckboxList.ItemTemplate> + <DataTemplate > + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data,Converter={StaticResource EnumToDescriptionConverter}}" FontSize="11" FontFamily="{StaticResource FontName}"/> + + </DataTemplate> + </controls:AllSelectedCheckboxList.ItemTemplate> + </controls:AllSelectedCheckboxList> </Border> </Popup> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/ViewModels/MainViewVM.cs index bbe5432e9..bb9608f6b 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DataCapture/ViewModels/MainViewVM.cs @@ -382,7 +382,7 @@ namespace Tango.MachineStudio.DataCapture.ViewModels using (_notification.PushTaskItem("Starting Recording...")) { Recorder.Start(); - _eventLogger.Log(EventTypes.RECORDING_STARTED, "Recording Started..."); + //_eventLogger.Log(EventTypes.RECORDING_STARTED, "Recording Started..."); _recordingBarItem.Push(); } @@ -398,7 +398,7 @@ namespace Tango.MachineStudio.DataCapture.ViewModels await Recorder.Stop(); _recordingBarItem.Pop(); - _eventLogger.Log(EventTypes.RECORDING_STOPPED, "Recording Stopped..."); + //_eventLogger.Log(EventTypes.RECORDING_STOPPED, "Recording Stopped..."); } String recordingName = _notification.ShowTextInput("Enter recording name", "Recording name"); 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 index 9f0ea3423..fc0680d9c 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -1257,7 +1257,7 @@ namespace Tango.MachineStudio.Developer.ViewModels || j.Name.ToLower().Contains(filter) //Job name || - j.User.Contact.FirstName.ToLower().Contains(filter) // User first name + (j.User != null && j.User.Contact.FirstName.ToLower().Contains(filter)) // User first name || j.Length.ToString().Contains(filter); //Job length }; @@ -1376,7 +1376,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// <summary> /// Starts the job. /// </summary> - private async void StartJob(Func<Job, JobHandler> resumeFunc = null) + private async void StartJob(Func<JobHandler> resumeFunc = null) { SettingsManager.Default.Save(); @@ -1441,7 +1441,7 @@ namespace Tango.MachineStudio.Developer.ViewModels } else { - JobHandler = resumeFunc(ActiveJob); + JobHandler = resumeFunc(); } _navigation.NavigateTo(DeveloperNavigationView.RunningJobView); @@ -1673,7 +1673,17 @@ namespace Tango.MachineStudio.Developer.ViewModels { await Task.Factory.StartNew(() => { - InvalidateLiquidFactorsAndProcessTables(); + try + { + IsFree = false; + InvalidateLiquidFactorsAndProcessTables(); + } + catch + {} + finally + { + IsFree = true; + } }); } } @@ -1709,12 +1719,12 @@ namespace Tango.MachineStudio.Developer.ViewModels { try { - LogManager.Log(String.Format("Uploading process parameters table {0}...", SelectedProcessParametersTable.Name)); + LogManager.Log($"Uploading process parameters table {SelectedProcessParametersTable.Name}..."); await MachineOperator.UploadProcessParameters(SelectedProcessParametersTable); } catch (Exception ex) { - LogManager.LogFormat(ex, "Failed to upload process parameters table {0}", SelectedProcessParametersTable.Name); + LogManager.Log(ex, $"Failed to upload process parameters table {SelectedProcessParametersTable.Name}"); _notification.ShowError("Failed to upload the selected process parameters." + Environment.NewLine + ex.Message); } } @@ -1849,7 +1859,7 @@ namespace Tango.MachineStudio.Developer.ViewModels //var processParams = _activeJobDbContext.ProcessParametersTables.ToList(); ColorSpaces = _activeJobDbContext.ColorSpaces.ToObservableCollection(); - Rmls = _activeJobDbContext.Rmls.ToObservableCollection(); + Rmls = _activeJobDbContext.Rmls.OrderBy(i => i.Name).ToObservableCollection(); WindingMethods = _activeJobDbContext.WindingMethods.ToObservableCollection(); SpoolTypes = _activeJobDbContext.SpoolTypes.ToObservableCollection(); @@ -2189,7 +2199,7 @@ namespace Tango.MachineStudio.Developer.ViewModels { if (ActiveJob != null) { - LogManager.LogFormat("Adding new segment to job {0}...", ActiveJob.Name); + LogManager.Log($"Adding new segment to job {ActiveJob.Name}..."); Segment seg = new Segment(); seg.Job = ActiveJob; seg.Name = "SEGMENT"; @@ -2321,7 +2331,13 @@ namespace Tango.MachineStudio.Developer.ViewModels return; } SelectedSegment.BrushStops.Remove(x); - _activeJobDbContext.BrushStops.Remove(x); + var existingBrushStop = _activeJobDbContext.BrushStops.FirstOrDefault(y => y.Guid == x.Guid); + if(existingBrushStop != null) + { + _activeJobDbContext.BrushStops.Remove(existingBrushStop); + } + + }); ArrangeBrushStopsIndices(); @@ -2336,7 +2352,7 @@ namespace Tango.MachineStudio.Developer.ViewModels { if (SelectedSegment != null) { - LogManager.LogFormat("Adding new brush stop to segment...", SelectedSegment.SegmentIndex.ToString()); + LogManager.Log($"Adding new brush stop to segment '{SelectedSegment.SegmentIndex}'..."); var stop = new BrushStop(); @@ -2356,6 +2372,7 @@ namespace Tango.MachineStudio.Developer.ViewModels stop.SetAllDispensingStepDivisions(BL.Dispensing.DispenserStepDivisions.D8); stop.SetLiquidVolumes(SelectedMachine.Configuration, SelectedRML, SelectedProcessParametersTable); SelectedSegment.BrushStops.Add(stop); + // _activeJobDbContext.BrushStops.Add(stop); SelectedSegment.BrushStops.ToList().ForEach(x => x.RaiseOffsetChanged()); ArrangeBrushStopsIndices(); } @@ -2366,7 +2383,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// </summary> private void DuplicateSelectedBrushStops() { - LogManager.LogFormat("Duplicating {0} brush stops...", SelectedBrushStops.Count); + LogManager.Log($"Duplicating {SelectedBrushStops.Count} brush stops..."); foreach (var stop in SelectedBrushStops.OrderBy(x => x.StopIndex)) { @@ -2384,7 +2401,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// </summary> private void DuplicateSelectedSegments() { - LogManager.LogFormat("Duplicating {0} segments...", SelectedSegments.Count); + LogManager.Log($"Duplicating {SelectedSegments.Count} segments..."); int start_index = SelectedSegments.Max(x => x.SegmentIndex); @@ -2412,7 +2429,7 @@ namespace Tango.MachineStudio.Developer.ViewModels { CanWork = false; - LogManager.LogFormat("Duplicating {0} jobs...", SelectedJobs.Count); + LogManager.Log($"Duplicating {SelectedJobs.Count} jobs..."); int index = SelectedMachine.Jobs.Max(x => x.JobIndex); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml index ed832f468..32b7ccd86 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml @@ -756,7 +756,7 @@ <StackPanel> <TextBlock>MEDIA</TextBlock> <StackPanel Orientation="Horizontal" DockPanel.Dock="Left"> - <ComboBox Width="250" ItemsSource="{Binding Rmls}" SelectedItem="{Binding SelectedRML}" Style="{StaticResource TransparentComboBoxStyle}" HorizontalContentAlignment="Stretch"> + <controls:SearchComboBox Width="250" ItemsSource="{Binding Rmls}" SelectedItem="{Binding SelectedRML}" HorizontalContentAlignment="Stretch" SearchProperty="Name"> <ComboBox.ItemTemplate> <DataTemplate> <DockPanel> @@ -771,7 +771,7 @@ </DockPanel> </DataTemplate> </ComboBox.ItemTemplate> - </ComboBox> + </controls:SearchComboBox> <!--<Button Margin="20 30 0 0" Command="{Binding EditRMLCommand}" HorizontalAlignment="Right" Style="{StaticResource MaterialDesignFlatButton}"> <StackPanel Orientation="Horizontal"> @@ -976,7 +976,8 @@ <Image Source="../Images/colorspace.png" Width="24"></Image> <TextBlock VerticalAlignment="Center" Margin="5 0 0 0" FontSize="10">Color Space</TextBlock> </StackPanel> - <ComboBox SelectionChanged="OnBrushStopColorSpace_SelectionChanged" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.ColorSpaces}" SelectedItem="{Binding ColorSpace}" DisplayMemberPath="Name" Width="100" HorizontalAlignment="Left"> + <ComboBox SelectionChanged="OnBrushStopColorSpace_SelectionChanged" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.ColorSpaces}" SelectedItem="{Binding ColorSpace}" DisplayMemberPath="Name" Width="100" HorizontalAlignment="Left" + Style="{StaticResource TransparentComboBoxStyle}" > <ComboBox.ItemContainerStyle> <Style TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}"> <Setter Property="Background" Value="{StaticResource WhiteBrush100}"></Setter> @@ -1519,7 +1520,7 @@ <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ContentControl"> - <Grid Width="97"> + <Grid Width="97" ToolTip="{Binding Name}" Background="Transparent" ToolTipService.InitialShowDelay="1000" ToolTipService.BetweenShowDelay="1000"> <Border> <Border.Style> <Style TargetType="Border"> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml index bf626f462..a3d2dbd68 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml @@ -125,7 +125,7 @@ <Grid Margin="0 20 0 0"> <commonControls:LoadingPanel IsLoading="{Binding CanWork,Converter={StaticResource BooleanInverseConverter}}"> - <controls:MultiSelectDataGrid MouseDoubleClick="MultiSelectDataGrid_MouseDoubleClick" AutomationProperties.AutomationId="{x:Static automation:Developer.JobsDataGrid}" Style="{StaticResource {x:Type DataGrid}}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeColumns="True" CanUserSortColumns="True" AutoGenerateColumns="False" Background="Transparent" ItemsSource="{Binding JobsCollectionView}" SelectedItem="{Binding SelectedMachineJob}" SelectedItemsList="{Binding SelectedJobs,Mode=TwoWay}"> + <controls:MultiSelectDataGrid DoubleClickCommand="{Binding LoadJobCommand}" AutomationProperties.AutomationId="{x:Static automation:Developer.JobsDataGrid}" Style="{StaticResource {x:Type DataGrid}}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeColumns="True" CanUserSortColumns="True" AutoGenerateColumns="False" Background="Transparent" ItemsSource="{Binding JobsCollectionView}" SelectedItem="{Binding SelectedMachineJob}" SelectedItemsList="{Binding SelectedJobs,Mode=TwoWay}"> <DataGrid.CellStyle> <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> <Setter Property="BorderThickness" Value="0"/> @@ -190,10 +190,10 @@ </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> - <DataGridTemplateColumn Header="CREATED BY" Width="100" CanUserSort="True" SortMemberPath="User"> + <DataGridTemplateColumn Header="CREATED BY" Width="100" CanUserSort="True" SortMemberPath="User.Contact.FirstName"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> - <TextBlock Text="{Binding User.Contact.FirstName}" VerticalAlignment="Center" FontSize="14"></TextBlock> + <TextBlock Text="{Binding User.Contact.FirstName,TargetNullValue='PPC',FallbackValue='PPC'}" VerticalAlignment="Center" FontSize="14"></TextBlock> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs index cf66c1a34..47fe19a05 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs @@ -261,7 +261,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels { using (var db = ObservablesContext.CreateDefault()) { - _hardwareVersions = db.HardwareVersions.ToObservableCollection(); + _hardwareVersions = db.HardwareVersions.OrderByDescending(x => x.Version).ToObservableCollection(); InvokeUI(() => { RaisePropertyChanged(nameof(HardwareVersions)); @@ -360,24 +360,34 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels { using (_notification.PushTaskItem("Loading hardware version...")) { - IsFree = false; - - await Task.Factory.StartNew(() => + try { - _isNew = false; - var selectedVersion = SelectedVersion; - RefreshVersions(); - var version = _hardwareVersions.SingleOrDefault(X => X.Guid == selectedVersion.Guid); - CreateVersionView(SelectedVersion); + IsFree = false; - InvokeUI(() => + await Task.Factory.StartNew(() => { - _selectedVersion = version; - RaisePropertyChanged(nameof(SelectedVersion)); - }); - }); + _isNew = false; + var selectedVersion = SelectedVersion; + RefreshVersions(); + var version = _hardwareVersions.SingleOrDefault(X => X.Guid == selectedVersion.Guid); + CreateVersionView(SelectedVersion); - IsFree = true; + InvokeUI(() => + { + _selectedVersion = version; + RaisePropertyChanged(nameof(SelectedVersion)); + }); + }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading hardware version."); + _notification.ShowError($"Error loading the selected hardware version.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml index 1c00397aa..9ee2ffee7 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml @@ -9,6 +9,7 @@ xmlns:editors="clr-namespace:Tango.SharedUI.Editors;assembly=Tango.SharedUI" xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:entities="clr-namespace:Tango.BL.Entities;assembly=Tango.BL" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:local="clr-namespace:Tango.MachineStudio.HardwareDesigner.Views" xmlns:vm="clr-namespace:Tango.MachineStudio.HardwareDesigner.ViewModels" xmlns:observables="clr-namespace:Tango.BL.Entities;assembly=Tango.BL" @@ -57,14 +58,14 @@ <TextBlock FontSize="30" FontStyle="Italic" VerticalAlignment="Center" Margin="50 10 10 0" Foreground="Silver" FontWeight="Bold">HARDWARE DESIGNER</TextBlock> <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="10 10 0 0"> <materialDesign:PackIcon Kind="Pencil" Width="32" Height="32" Foreground="Silver" /> - <ComboBox IsEnabled="{Binding IsFree}" ItemsSource="{Binding HardwareVersions}" SelectedItem="{Binding SelectedVersion}" Width="300" FontSize="16" FontWeight="Bold" Margin="5 0 0 0" materialDesign:HintAssist.Hint="Hardware Version"> + <controls:SearchComboBox IsEnabled="{Binding IsFree}" ItemsSource="{Binding HardwareVersions}" SelectedItem="{Binding SelectedVersion}" Width="300" SearchProperty="FullName" FontSize="16" FontWeight="Bold" Margin="5 0 0 0" materialDesign:HintAssist.Hint="Hardware Version"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock><Run Text="{Binding Name}"></Run> <Run></Run> <Run Foreground="{StaticResource MainWindow.Foreground}" FontSize="14">v</Run><Run Foreground="{StaticResource MainWindow.Foreground}" FontSize="14" Text="{Binding Version}"></Run></TextBlock> </DataTemplate> </ComboBox.ItemTemplate> - </ComboBox> - + </controls:SearchComboBox> + </StackPanel> <Button Margin="100 10 0 0" Cursor="Hand" Height="40" FontSize="12" ToolTip="Open Comparison Wizard" Command="{Binding OpenComparisonWizardCommand}"> <StackPanel Orientation="Horizontal"> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index ed93b4308..9c4c2281d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -39,6 +39,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels private ActionTimer _machines_action_timer; private ActionTimer _dispensers_action_timer; private MachineDTO _machineBeforeSave; + private List<Site> _all_sites; #region Properties @@ -609,11 +610,15 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } } } + ActiveMachine.OrganizationChanged -= ActiveMachine_OrganizationChanged; + ActiveMachine.OrganizationChanged += ActiveMachine_OrganizationChanged; - var sites = await ActiveMachineAdapter.Context.Sites.ToListAsync(); - sites.Insert(0, new Site() { Name = "NONE", ID = -1 }); + _all_sites = await ActiveMachineAdapter.Context.Sites.ToListAsync(); + var sites = ActiveMachine.Organization != null ? _all_sites.Where(x => x.OrganizationGuid == ActiveMachine.OrganizationGuid).ToList() : new List<Site>(); + sites.Insert(0, new Site() { Name = "NONE", ID = -1 }); Sites = sites; + SelectedSite = Sites.SingleOrDefault(x => x.Guid == ActiveMachine.SiteGuid); ColorCalibrationViewVM = new ColorCalibrationViewVM(_notification, ActiveMachine, _activeMachineAdapter.Context) @@ -997,5 +1002,14 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels }); } } + + private void ActiveMachine_OrganizationChanged(object sender, Organization e) + { + var sites = ActiveMachine.Organization != null ? _all_sites.Where(x => x.OrganizationGuid == ActiveMachine.OrganizationGuid).ToList() : new List<Site>(); + sites.Insert(0, new Site() { Name = "NONE", ID = -1 }); + Sites = sites; + + SelectedSite = Sites.SingleOrDefault(x => x.Guid == ActiveMachine.SiteGuid); + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml index 954ac5f0e..76517ec37 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml @@ -51,10 +51,10 @@ <TextBox Text="{Binding ActiveMachine.Name}"></TextBox> <TextBlock FontWeight="SemiBold">Head Type</TextBlock> - <ComboBox ItemsSource="{Binding Source={x:Type enumerations:HeadTypes},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValue="{Binding ActiveMachine.MachineHeadType}" SelectedValuePath="Value" DisplayMemberPath="DisplayName"></ComboBox> + <ComboBox ItemsSource="{Binding Source={x:Type enumerations:HeadTypes},Converter={StaticResource EnumToItemsSourceConverter}}" SelectedValue="{Binding ActiveMachine.MachineHeadType}" SelectedValuePath="Value" DisplayMemberPath="DisplayName" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> <TextBlock FontWeight="SemiBold">Machine Version</TextBlock> - <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.MachineVersions}" SelectedItem="{Binding ActiveMachine.MachineVersion}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> + <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.MachineVersions}" SelectedItem="{Binding ActiveMachine.MachineVersion}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}" ></ComboBox> <TextBlock FontWeight="SemiBold">Organization</TextBlock> <ComboBox Background="Transparent" ItemsSource="{Binding ActiveMachineAdapter.Organizations}" SelectedItem="{Binding ActiveMachine.Organization}" DisplayMemberPath="Name" Style="{StaticResource TransparentComboBoxStyle}"></ComboBox> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Models/CalibrationMeasurementModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Models/CalibrationMeasurementModel.cs new file mode 100644 index 000000000..6345d5f59 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Models/CalibrationMeasurementModel.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.BL.Enumerations; +using Tango.PMR.Printing; + +namespace Tango.MachineStudio.RML.Models +{ + public static class ColorCalibrationExt + { + public static Dictionary<LiquidTypes, LAB> TargetLiquidTypeToLAB = new Dictionary<LiquidTypes, LAB> + { + {LiquidTypes.Cyan, new LAB(51.94591,-18.3438,-39.0577)}, + {LiquidTypes.Magenta, new LAB(47.46248, 65.84478, 3.922838)}, + {LiquidTypes.Yellow, new LAB(84.41956,-0.27005, 94.05445)}, + {LiquidTypes.Black, new LAB(26.57986, -0.13567, 0.948574)}, + }; + public static Dictionary<LiquidTypes, string> DisplayLiquidTypeToLABType = new Dictionary<LiquidTypes, string> + { + {LiquidTypes.Cyan, "L"}, + {LiquidTypes.Magenta, "L"}, + {LiquidTypes.Yellow, "B"}, + {LiquidTypes.Black, "L"}, + }; + }; + + public class LAB + { + public double L { get; set; } + public double A { get; set; } + public double B { get; set; } + + public LAB( double l, double a, double b) + { + L = l; B = b; A = a; + } + }; + + public class CalibrationMeasurementModel : ExtendedObject + { + #region properties + private double _l; + + public double L + { + get { return _l; } + set { _l = value; RaisePropertyChangedAuto(); } + } + + private double _a; + + public double A + { + get { return _a; } + set { _a = value; RaisePropertyChangedAuto(); } + } + + private double _b; + + public double B + { + get { return _b; } + set { _b = value; RaisePropertyChangedAuto(); } + } + + private double _ink; + + public double Ink + { + get { return _ink; } + set { _ink = value; RaisePropertyChangedAuto(); } + } + #endregion + + public CalibrationMeasurementModel() + { + + } + public CalibrationMeasurementModel(Tango.MachineStudio.RML.Models.ColorLinearizationModel.LinearizationDataItem model) + { + L = model.L; + A = model.A; + B = model.B; + Ink = model.InkPercentage; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Models/ColorLinearizationModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Models/ColorLinearizationModel.cs new file mode 100644 index 000000000..23179b3f2 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Models/ColorLinearizationModel.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Documents; + +namespace Tango.MachineStudio.RML.Models +{ + public class ColorLinearizationModel + { + public class LinearizationDataItem + { + public double InkPercentage { get; set; } + public double L { get; set; } + public double A { get; set; } + public double B { get; set; } + } + + public ColorLinearizationModel() + { + + } + + public void GetDataFromFile(string fileName, out List<LinearizationDataItem> items, ref string errors) + { + items = null; + try + { + using (ExcelReader reader = new ExcelReader(fileName)) + { + items = reader.GetDataByIndex<LinearizationDataItem>("Sheet1", 2); + } + } + catch (Exception ex) + { + errors = ex.Message; + } + + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Tango.MachineStudio.RML.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Tango.MachineStudio.RML.csproj index a413223c3..38d289c58 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Tango.MachineStudio.RML.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Tango.MachineStudio.RML.csproj @@ -49,6 +49,12 @@ <Reference Include="MaterialDesignThemes.Wpf, Version=2.3.1.953, Culture=neutral, processorArchitecture=MSIL"> <HintPath>..\..\..\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll</HintPath> </Reference> + <Reference Include="OxyPlot"> + <HintPath>..\..\..\packages\OxyPlot.Core.2.0.0\lib\net45\OxyPlot.dll</HintPath> + </Reference> + <Reference Include="OxyPlot.Wpf"> + <HintPath>..\..\..\packages\OxyPlot.Wpf.2.0.0\lib\net45\OxyPlot.Wpf.dll</HintPath> + </Reference> <Reference Include="System" /> <Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.Data" /> @@ -73,7 +79,9 @@ <Link>GlobalVersionInfo.cs</Link> </Compile> <Compile Include="Contracts\IMainView.cs" /> + <Compile Include="Models\CalibrationMeasurementModel.cs" /> <Compile Include="Models\CctModel.cs" /> + <Compile Include="Models\ColorLinearizationModel.cs" /> <Compile Include="RMLModule.cs" /> <Compile Include="Properties\AssemblyInfo.cs"> <SubType>Code</SubType> @@ -93,16 +101,21 @@ <Compile Include="ViewModels\CalibrationDataPointVM.cs" /> <Compile Include="ViewModels\CalibrationDataViewVM.cs" /> <Compile Include="ViewModels\CalibrationDataVM.cs" /> + <Compile Include="ViewModels\ColorCalibrationViewVM.cs" /> <Compile Include="ViewModels\ColorConversionViewVM.cs" /> <Compile Include="ViewModels\LiquidVolumeVM.cs" /> <Compile Include="ViewModels\MainViewVM.cs" /> <Compile Include="ViewModels\RgbVM.cs" /> + <Compile Include="ViewModels\RmlDeleteDialogViewVM.cs" /> <Compile Include="Views\AddLiquidFactorView.xaml.cs"> <DependentUpon>AddLiquidFactorView.xaml</DependentUpon> </Compile> <Compile Include="Views\CalibrationDataView.xaml.cs"> <DependentUpon>CalibrationDataView.xaml</DependentUpon> </Compile> + <Compile Include="Views\ColorCalibrationView.xaml.cs"> + <DependentUpon>ColorCalibrationView.xaml</DependentUpon> + </Compile> <Compile Include="Views\ColorConversionView.xaml.cs"> <DependentUpon>ColorConversionView.xaml</DependentUpon> </Compile> @@ -112,6 +125,9 @@ <Compile Include="Views\ProcessParametersView.xaml.cs"> <DependentUpon>ProcessParametersView.xaml</DependentUpon> </Compile> + <Compile Include="Views\RmlDeleteDialogView.xaml.cs"> + <DependentUpon>RmlDeleteDialogView.xaml</DependentUpon> + </Compile> <Compile Include="Views\RmlsView.xaml.cs"> <DependentUpon>RmlsView.xaml</DependentUpon> </Compile> @@ -151,6 +167,10 @@ <Project>{40085232-aced-4cbe-945b-90ba8153c151}</Project> <Name>Tango.BrushPicker</Name> </ProjectReference> + <ProjectReference Include="..\..\..\Tango.ColorCalibration\Tango.ColorCalibration.csproj"> + <Project>{b60c695c-61e8-4091-b506-4c45349c04aa}</Project> + <Name>Tango.ColorCalibration</Name> + </ProjectReference> <ProjectReference Include="..\..\..\Tango.ColorConversion\Tango.ColorConversion.csproj"> <Project>{b4fe6485-4161-4b36-bc08-67e0b53d01b7}</Project> <Name>Tango.ColorConversion</Name> @@ -212,6 +232,10 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </Page> + <Page Include="Views\ColorCalibrationView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\ColorConversionView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> @@ -224,6 +248,10 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Views\RmlDeleteDialogView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Views\RmlsView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/CalibrationDataViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/CalibrationDataViewVM.cs index b34ef83bc..fd69fef35 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/CalibrationDataViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/CalibrationDataViewVM.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL.Calibration; +using Tango.BL.Entities; using Tango.Core.Commands; using Tango.MachineStudio.Common; using Tango.MachineStudio.Common.Notifications; @@ -106,5 +107,14 @@ namespace Tango.MachineStudio.RML.ViewModels _notification.ShowError("An error occurred while trying to export the calibration data."); } } + + public void ApplyCalibrationData(LiquidType liquidType, List<CalibrationDataPointVM> newpoints) + { + CalibrationDataVM vm = LiquidsCalibrationData.FirstOrDefault(x => x.LiquidType == liquidType); + if(vm != null) + { + newpoints.ForEach(x => vm.CalibrationPoints.Add(x)); + } + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorCalibrationViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorCalibrationViewVM.cs new file mode 100644 index 000000000..f04eccd90 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorCalibrationViewVM.cs @@ -0,0 +1,551 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core; +using Tango.Core.Commands; +using Tango.MachineStudio.RML.Models; +using Tango.SharedUI; +using OxyPlot; +using OxyPlot.Wpf; +using OxyPlot.Annotations; +using Tango.ColorCalibration; +using Tango.PMR.ColorLab; +using Tango.Logging; +using Tango.MachineStudio.Common.Notifications; +using System.Text.RegularExpressions; +using Microsoft.Win32; + +namespace Tango.MachineStudio.RML.ViewModels +{ + public class ColorCalibrationViewVM : ExtendedObject + { + private IColorCalibrator _calibrator; + private ILinearizationMeasurements _linearizationMeasurementscalibrator; + private INotificationProvider _notification; + + #region Properties + + private Rml _rml; + public Rml RML + { + get { return _rml; } + set { _rml = value; RaisePropertyChangedAuto(); } + } + + private BL.Entities.LiquidType _liquidType; + + public BL.Entities.LiquidType LiquidType + { + get { return _liquidType; } + set { _liquidType = value; RaisePropertyChangedAuto(); RaisePropertyChanged("LiquidTypeName"); } + } + + private List<BL.Entities.LiquidType> _liquidTypes; + + public List<BL.Entities.LiquidType> LiquidTypes + { + get { return _liquidTypes; } + set { _liquidTypes = value; } + } + + + private ObservableCollection<CalibrationMeasurementModel> _measurements; + public ObservableCollection<CalibrationMeasurementModel> Measurements + { + get + { + return _measurements; + } + set + { + _measurements = value; RaisePropertyChangedAuto(); + } + } + + + private double _factor; + + public double Factor + { + get { return _factor; } + set { _factor = value; RaisePropertyChangedAuto(); } + } + + private string _errorMessage; + + public string ErrorMessage + { + get { return _errorMessage; } + set { _errorMessage = value; RaisePropertyChangedAuto(); } + } + private bool _hasError; + + public bool HasError + { + get { return _hasError; } + set { _hasError = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand ImportDataCommand { get; set; } + public RelayCommand CreateGraphCommand { get; set; } + public RelayCommand CreateLinearizationGraphCommand { get; set; } + public RelayCommand ExportGraphCommand { get; set; } + public RelayCommand ApplyCalibrationDataCommand { get; set; } + + + public string LiquidTypeName + { + get { return LiquidType == null ?"" : LiquidType.Name; } + } + + public Plot PlotControl { get; set; } + private IList<DataPoint> _points; + /// <summary> + /// Binding to ItemsSource of line chart. + /// </summary> + public IList<DataPoint> Points + { + get { return _points; } + set + { + _points = value; + RaisePropertyChangedAuto(); + } + } + private IList<DataPoint> _targetPoints; + /// <summary> + /// Binding to ItemsSource of line chart. + /// </summary> + public IList<DataPoint> TargetPoints + { + get { return _targetPoints; } + set + { + _targetPoints = value; + RaisePropertyChangedAuto(); + } + } + private int _step; + public int XStep + { + get { return _step; } + set { _step = value; RaisePropertyChangedAuto(); } + } + + private double _from; + /// <summary> + /// From use to binding to bottom axis min value + /// </summary> + public double From + { + get { return _from; } + set + { + _from = value; RaisePropertyChangedAuto(); + } + } + + private double _to; + /// <summary> + /// To use to binding to bottom axis max value + /// </summary> + public double To + { + get { return _to; } + set + { + _to = value; RaisePropertyChangedAuto(); + } + } + + private double _LabMinVal; + + public double LabMinVal + { + get { return _LabMinVal; } + set { _LabMinVal = value; RaisePropertyChangedAuto(); } + } + + private double _LabMaxVal; + + public double LabMaxVal + { + get { return _LabMaxVal; } + set { _LabMaxVal = value; RaisePropertyChangedAuto(); } + } + + public Plot LABLinearizationPlotControl { get; set; } + public Plot LinearizationPlotControl { get; set; } + private IList<DataPoint> _linearizationPoints; + /// <summary> + /// Binding to ItemsSource of line chart. + /// </summary> + public IList<DataPoint> LinearizationPoints + { + get { return _linearizationPoints; } + set + { + _linearizationPoints = value; + RaisePropertyChangedAuto(); + } + } + + private IList<DataPoint> _LPoints; + + public IList<DataPoint> LPoints + { + get { return _LPoints; } + set { _LPoints = value; } + } + + private IList<DataPoint> _APoints; + + public IList<DataPoint> APoints + { + get { return _APoints; } + set { _APoints = value; } + } + + private IList<DataPoint> _BPoints; + + public IList<DataPoint> BPoints + { + get { return _BPoints; } + set { _BPoints = value; } + } + + + #endregion + + public ColorCalibrationViewVM(INotificationProvider notification) + { + _notification = notification; + Measurements = new ObservableCollection<CalibrationMeasurementModel>() + { + new CalibrationMeasurementModel(), + new CalibrationMeasurementModel(), + new CalibrationMeasurementModel(), + }; + Factor = 0; + HasError = false; + ImportDataCommand = new RelayCommand(ImportDataForCalcFactorExcel); + CreateGraphCommand = new RelayCommand(CreateGraph); + CreateLinearizationGraphCommand = new RelayCommand(CreateLinearizationGraph); + ExportGraphCommand = new RelayCommand(ExportGraph); + ApplyCalibrationDataCommand = new RelayCommand(ApplyCalibrationData); + this.Points = new List<DataPoint>(); + TargetPoints = new List<DataPoint>(); + LinearizationPoints = new List<DataPoint>(); + LPoints = new List<DataPoint>(); + APoints = new List<DataPoint>(); + BPoints = new List<DataPoint>(); + } + + public void Loading() + { + LiquidType = LiquidTypes.Count > 0 ? LiquidTypes[0] : null; + _calibrator = new DefaultColorCalibrator(); + _linearizationMeasurementscalibrator = new DefaultColorCalibrator(); + + } + + public void ClearResults() + { + Points.Clear(); + TargetPoints.Clear(); + ErrorMessage = ""; + HasError = false; + Factor = 0.0; + } + + private double GetLiquidFactor() + { + try + { + CalibrationInput conversionInput = new CalibrationInput(); + Measurements.ToList().ForEach(x => conversionInput.Measurements.Add(new CalibrationMeasurement { L = x.L, A = x.A, B = x.B, NanoliterPerCentimeter = x.Ink })); + conversionInput.LiquidType = PMR.ColorLab.LiquidType.TryParse(_liquidType.Type.ToString(), out PMR.ColorLab.LiquidType outValue) ? outValue : PMR.ColorLab.LiquidType.Black; + + + LAB lab; + if (ColorCalibrationExt.TargetLiquidTypeToLAB.TryGetValue(_liquidType.Type, out lab)) + { + conversionInput.TargetL = lab.L; + conversionInput.TargetA = lab.A; + conversionInput.TargetB = lab.B; + } + CalibrationOutput result = _calibrator.GetLiquidFactor(conversionInput); + + ErrorMessage = result.ErrorMessage; + HasError = false == String.IsNullOrEmpty(ErrorMessage); + + return result.LiquidFactor; + } + catch (Exception ex ) + { + HasError = true; + ErrorMessage = "Error occurred while trying to call GetLiquidFactor."; + LogManager.Log(ex, "Error occurred while trying to call GetLiquidFactor."); + } + return 0.0; + } + + private void ImportDataForCalcFactorExcel() + { + OpenFileDialog dlg = new OpenFileDialog(); + + try + { + dlg.Title = $"Import excel file for calculate Factor"; + dlg.Filter = "Excel Files|*.xlsx"; + if (dlg.ShowDialog().Value) + { + ClearResults(); + + List<ColorLinearizationModel.LinearizationDataItem> items;//List<LinearizationDataItem> items + ColorLinearizationModel model = new ColorLinearizationModel(); + string error = ""; + model.GetDataFromFile(dlg.FileName, out items, ref error); + if (false == String.IsNullOrEmpty(error) || items == null || items.Count == 0) + { + _notification.ShowError("An error occurred while trying to import data form the selected excel file. Please check the file format if valid and is available to read."); + return; + } + Measurements.Clear(); + items.ForEach(x => Measurements.Add(new CalibrationMeasurementModel(x))); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error importing excel file " + dlg.FileName); + _notification.ShowError("An error occurred while trying to import the selected excel file. Please check the file format if valid and is available to read."); + } + } + #region CreateGraph + + private async void CreateGraph(object obj) + { + if (_liquidType == null) + return; + ClearResults(); + PlotControl.InvalidatePlot(true); + string labType = ColorCalibrationExt.DisplayLiquidTypeToLABType[_liquidType.Type]; + await Task.Factory.StartNew(() => + { + Factor = GetLiquidFactor( ); + }); + + DataPoint targetPoint = GetTargetPoint(); + + To = 0; + From = 0; + + Measurements.ToList().ForEach(x =>{ Points.Add(new DataPoint(x.Ink, labType == "L" ? x.L : x.B)); + TargetPoints.Add(new DataPoint(x.Ink, targetPoint.Y)); }); + + _to = labType == "L"? 100 : 128; + _from = labType == "L" ? 0 : -127; + + RaisePropertyChanged("To"); + RaisePropertyChanged("From"); + XStep = (int)(Points.Count / 6); + RaisePropertyChanged("CalibrationType"); + PlotControl.InvalidatePlot(true); + + } + + private DataPoint GetTargetPoint() + { + var listValues = Measurements.ToList(); + if (listValues.Count == 0 || Factor <=0) + return new DataPoint(0, 0); + + string labType = ColorCalibrationExt.DisplayLiquidTypeToLABType[_liquidType.Type]; + + var left = listValues.Where(y => y.Ink == listValues.Min(x => x.Ink)).ToList().First(); + var right = listValues.Where(y => y.Ink == listValues.Max(x => x.Ink)).ToList().First(); + // Normalize start/end to left right to make the offset calc simpler. + DataPoint leftPoint = new DataPoint(left.Ink, labType == "L" ? left.L : left.B); + DataPoint rightPoint = new DataPoint(right.Ink, labType == "L" ? right.L : right.B); + + double deltaX = rightPoint.X - leftPoint.X; + double deltaY = rightPoint.Y - leftPoint.Y; + + // prevents division by zero exceptions. + if (deltaX == 0 ) + return new DataPoint(0, 0); + + double slope = deltaY / deltaX; + double offset = leftPoint.Y - leftPoint.X * slope; + double calculatedY = Factor * slope + offset; + + return new DataPoint(Factor, calculatedY); ; + } + + #endregion + #region CreateLinearizationGraph + + private async void CreateLinearizationGraph(object obj) + { + if (_liquidType == null ) + return; + + string labType = ColorCalibrationExt.DisplayLiquidTypeToLABType[_liquidType.Type]; + + ColorLinearizationModel model = new ColorLinearizationModel(); + string fileName = GetInkDataFileOpen();// @"C:\Test\Test Input Lineration.xlsx";//dialog to open file + if (fileName == null) + return; + + LinearizationPoints.Clear(); + LinearizationPlotControl.InvalidatePlot(true); + LPoints.Clear(); + APoints.Clear(); + BPoints.Clear(); + LabMinVal = LabMaxVal = 0; + LABLinearizationPlotControl.InvalidatePlot(true); + + List<ColorLinearizationModel.LinearizationDataItem> items; + string errors = ""; + model.GetDataFromFile(fileName, out items, ref errors); + if(false == String.IsNullOrEmpty(errors) || items == null || items.Count == 0) + { + _notification.ShowError("An error occurred while trying to import data form the selected excel file. Please check the file format if valid and is available to read."); + return; + } + + List<double> outputPoints = new List<double>(); + + await Task.Factory.StartNew(() => + { + outputPoints = GetLinearizationMeasurements(items); + }); + + LabMinVal = items.Min(x => Math.Min(x.L, Math.Min(x.A, x.B))); + LabMaxVal = items.Max(x => Math.Max(x.L, Math.Max(x.A, x.B))); + foreach (var labItem in items) + { + LPoints.Add(new DataPoint(labItem.InkPercentage, labItem.L)); + APoints.Add(new DataPoint(labItem.InkPercentage, labItem.A)); + BPoints.Add(new DataPoint(labItem.InkPercentage, labItem.B)); + } + LABLinearizationPlotControl.InvalidatePlot(true); + + if (outputPoints == null || outputPoints.Count != items.Count) + return; + + foreach (var nw in items.Zip(outputPoints, Tuple.Create)) + { + LinearizationPoints.Add(new DataPoint(nw.Item1.InkPercentage, nw.Item2)); + } + + LinearizationPlotControl.InvalidatePlot(true); + } + + /// <summary> + /// Open file dialog and get name of file + /// </summary> + /// <returns></returns> + private String GetInkDataFileOpen() + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Title = "Select Ink data file"; + dlg.Filter = "Excel |*.xlsx"; + if (dlg.ShowDialogCenter()) + { + return dlg.FileName; + } + + return null; + } + + private List<double> GetLinearizationMeasurements(List<ColorLinearizationModel.LinearizationDataItem> items) + { + try + { + LinearizationInput linearizationInput = new LinearizationInput(); + items.ForEach(x => linearizationInput.Measurements.Add(new LinearizationMeasurement { L = x.L, A = x.A, B = x.B, InkPercentage = x.InkPercentage })); + linearizationInput.LiquidType = PMR.ColorLab.LiquidType.TryParse(_liquidType.Type.ToString(), out PMR.ColorLab.LiquidType outValue) ? outValue : PMR.ColorLab.LiquidType.Black; + + LinearizationOutput result = _linearizationMeasurementscalibrator.GetLinearizationMeasurements(linearizationInput); + + if(!String.IsNullOrEmpty(result.ErrorMessage)) + { + LogManager.Log(result.ErrorMessage, "GetLinearizationMeasurements returns error." + result.ErrorMessage); + InvokeUI(() => + { + _notification.ShowError("Linearization failed. " + result.ErrorMessage); + }); + } + + LAB lab; + if (ColorCalibrationExt.TargetLiquidTypeToLAB.TryGetValue(_liquidType.Type, out lab)) + { + linearizationInput.TargetL = lab.L; + linearizationInput.TargetA = lab.A; + linearizationInput.TargetB = lab.B; + } + return result.InkPercentage.ToList(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to call GetLinearizationMeasurements."); + } + return null; + } + #endregion + + #region Export graph + /// <summary> + /// Exports the graph point to Excel file. + /// </summary> + protected void ExportGraph() + { + SaveFileDialog dlg = new SaveFileDialog(); + try + { + dlg.Title = $"Export excel calibration file for {LiquidType.Name}"; + dlg.Filter = "Excel Files|*.xlsx"; + dlg.DefaultExt = ".xlsx"; + dlg.FileName = $"CData_{LiquidType.Name}_v{LiquidType.Version}.xlsx"; + if (dlg.ShowDialog().Value) + { + List<CalibrationPoint> points = new List<CalibrationPoint>(); + LinearizationPoints.ToList().ForEach(x=> points.Add(ToCalibrationPoint(x))); + BL.Calibration.CalibrationHelper.ExportCalibrationDataToExcel(points, dlg.FileName); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error exporting excel file " + dlg.FileName); + _notification.ShowError("An error occurred while trying to export the calibration data."); + } + } + public CalibrationPoint ToCalibrationPoint(DataPoint point) + { + return new CalibrationPoint() + { + X = point.X, + Y = point.Y, + }; + } + + /// <summary> + /// Applies the calibration data. + /// </summary> + protected void ApplyCalibrationData() + { + if (LinearizationPoints.Count == 0) + return; + + List<CalibrationDataPointVM> points = new List<CalibrationDataPointVM>(); + LinearizationPoints.ToList().ForEach(x => points.Add(new CalibrationDataPointVM(x.X, x.Y))); + ViewModelLocator.MainViewVM.CalibrationDataViewVM.ApplyCalibrationData(LiquidType, points); + } + #endregion + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs index f583fa15e..95de19f42 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorConversionViewVM.cs @@ -111,6 +111,7 @@ namespace Tango.MachineStudio.RML.ViewModels Color = x.LiquidType.Color, Name = x.LiquidType.Name, LiquidType = x.LiquidType, + MaxNanoliterPerCentimeter = x.MaxNlPerCm, }).ToObservableCollection(); } @@ -309,16 +310,16 @@ namespace Tango.MachineStudio.RML.ViewModels } } - private double GetTotalMaximumLiquidVolumeLimit() + private double GetTotalMaximumLiquidNlPerCMLimit() { try { var tables = RML.GetActiveProcessGroup().ProcessParametersTables.OrderBy(x => x.TableIndex).ToList(); - return (tables[1].MaxInkUptake / tables[0].MaxInkUptake) * 100; + return tables.Max(x => x.MaxInkUptake); } catch { - return BrushStop.MAX_TOTAL_LIQUID_VOLUME; + return BrushStop.MAX_INK_UPTAKE; } } @@ -329,7 +330,7 @@ namespace Tango.MachineStudio.RML.ViewModels if (LiquidsCalibrationData == null || _prevent_inverse_conversion) return; //TODO: This is temporary because of out of range volumes. - if (LiquidVolumes.Where(x => x.LiquidType.HasPigment).Sum(x => x.Volume) > GetTotalMaximumLiquidVolumeLimit()) + if (LiquidVolumes.Where(x => x.LiquidType.HasPigment).Sum(x => x.NanoliterPerCentimeter) > GetTotalMaximumLiquidNlPerCMLimit()) { IsVolumesOutOfRange = true; return; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/LiquidVolumeVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/LiquidVolumeVM.cs index 7399d62af..27b811bb6 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/LiquidVolumeVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/LiquidVolumeVM.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Dispensing; using Tango.BL.Entities; using Tango.Core; using Tango.SharedUI; @@ -47,5 +48,17 @@ namespace Tango.MachineStudio.RML.ViewModels get { return _liquidType; } set { _liquidType = value; RaisePropertyChangedAuto(); } } + + public double MaxNanoliterPerCentimeter { get; set; } + + public double NanoliterPerCentimeter + { + get + { + StandardColorDispensingCalc calc = new StandardColorDispensingCalc(); + return calc.CalculateNanoliterPerCentimeter(Volume, MaxNanoliterPerCentimeter); + } + } + } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs index 1ceaf07df..cadd1fb95 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs @@ -45,6 +45,20 @@ namespace Tango.MachineStudio.RML.ViewModels set { _rmls = value; RaisePropertyChangedAuto(); } } + private ICollectionView _rmlssCollectionView; + /// <summary> + /// Gets or sets the RML collection view. + /// </summary> + public ICollectionView RmlsCollectionView + { + get { return _rmlssCollectionView; } + set + { + _rmlssCollectionView = value; + RaisePropertyChangedAuto(); + } + } + private ObservableCollection<MediaMaterial> _materials; public ObservableCollection<MediaMaterial> Materials { @@ -164,6 +178,22 @@ namespace Tango.MachineStudio.RML.ViewModels set { _selectedSpool = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } + private ColorCalibrationViewVM _colorCalibrationVM; + public ColorCalibrationViewVM ColorCalibrationVM + { + get { return _colorCalibrationVM; } + set { _colorCalibrationVM = value; RaisePropertyChangedAuto(); } + } + + private String _RMLFilter; + /// <summary> + /// Gets or sets the job filter. + /// </summary> + public String RMLFilter + { + get { return _RMLFilter; } + set { _RMLFilter = value; RaisePropertyChangedAuto(); OnRMLFilterChanged(); } + } /// <summary> /// Gets or sets the manage RML command. @@ -252,31 +282,57 @@ namespace Tango.MachineStudio.RML.ViewModels private async void LoadRmls() { - if (_rmls_context != null) _rmls_context.Dispose(); + try + { + IsFree = false; - _rmls_context = ObservablesContext.CreateDefault(); - Rmls = await new RmlsCollectionBuilder(_rmls_context).SetAll().WithLiquidFactors().WithMediaProperties().BuildAsync(); + using (_notification.PushTaskItem("Loading Rmls...")) + { + if (_rmls_context != null) _rmls_context.Dispose(); - //Load CCT file names... - var ccts = await _rmls_context.Ccts.Select(x => new - { - x.Guid, - x.FileName - }).ToListAsync(); + _rmls_context = ObservablesContext.CreateDefault(); + Rmls = await new RmlsCollectionBuilder(_rmls_context).SetAll().WithLiquidFactors().WithMediaProperties().BuildAsync(); + //Load CCT file names... + var ccts = await _rmls_context.Ccts.Select(x => new + { + x.Guid, + x.FileName + }).ToListAsync(); - foreach (var rml in Rmls) - { - var cct = ccts.SingleOrDefault(x => x.Guid == rml.CctGuid); + foreach (var rml in Rmls) + { + var cct = ccts.SingleOrDefault(x => x.Guid == rml.CctGuid); - if (cct != null) - { - rml.Cct = new Cct() + if (cct != null) + { + rml.Cct = new Cct() + { + Guid = cct.Guid, + FileName = cct.FileName, + }; + } + } + RmlsCollectionView = CollectionViewSource.GetDefaultView(Rmls); + RmlsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Rml.LastUpdated), ListSortDirection.Descending)); + //RmlsCollectionView.Filter = new Predicate<object>(FilterCollection); + + RmlsCollectionView.Filter = (rml) => { - Guid = cct.Guid, - FileName = cct.FileName, + Rml r = rml as Rml; + return String.IsNullOrWhiteSpace(RMLFilter) + || r.Name.ToLower().Contains(RMLFilter.ToLower()); }; + } } + catch (Exception ex) + { + LogManager.Log(ex, $"Error loading RMLS.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } } private async void LoadActiveRML(String guid) @@ -374,6 +430,12 @@ namespace Tango.MachineStudio.RML.ViewModels LiquidTypesRmls = LiquidTypesRmls, }; + ColorCalibrationVM = new ColorCalibrationViewVM(_notification) + { + RML = ActiveRML, + LiquidTypes = LiquidTypesRmls.Where(x => x.LiquidType.HasPigment).ToList().Select(y => y.LiquidType).ToList(), + }; + _rmlBeforeSave = RmlDTO.FromObservable(ActiveRML); View.NavigateTo(RmlNavigationView.RmlView); @@ -456,7 +518,7 @@ namespace Tango.MachineStudio.RML.ViewModels rml.DisplayName = name; rml.QualificationDate = DateTime.UtcNow; rml.Manufacturer = "Twine"; - rml.Code = Rmls.Max(x => x.Code) + 1; + rml.Code = Rmls.Count > 0 ? Rmls.Max(x => x.Code) + 1 : 1; rml.MediaMaterial = Materials.FirstOrDefault(); rml.MediaPurpose = Purposes.FirstOrDefault(); rml.MediaCondition = Conditions.FirstOrDefault(); @@ -492,34 +554,62 @@ namespace Tango.MachineStudio.RML.ViewModels { if (_notification.ShowQuestion("Removing the selected thread will result in the loss of all related process parameters and default calibration data. Are you sure you want to delete the selected RML?")) { - IsFree = false; - using (_notification.PushTaskItem("Removing RML...")) { try { + IsFree = false; + var rml_jobs = await _rmls_context.Jobs.Where(x => x.RmlGuid == SelectedRML.Guid).Include(x => x.Machine).OrderBy(x => x.Machine.SerialNumber).ToListAsync(); if (rml_jobs.Count > 0) { - _notification.ShowError($"The following jobs must be removed or change thread type before the selected thread can be deleted:\n{String.Join("\n", rml_jobs.Select(x => $"{x.Machine.SerialNumber} => {x.Name}"))}"); - return; + var vm = new RmlDeleteDialogViewVM(SelectedRML, Rmls.ToList(), rml_jobs.ToList()); + _notification.ShowModalDialog<RmlDeleteDialogViewVM, RmlDeleteDialogView>(vm, (x) => { }, () => { }); + + if (!vm.DialogResult) + { + return; + } + + //Perform actions... + using (var db = ObservablesContext.CreateDefault()) + { + foreach (var jobAction in vm.JobsActions) + { + if (jobAction.Action == RmlDeleteDialogViewVM.RmlDeleteJobAction.Delete) + { + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.JobDeleted, _authentication.CurrentUser.Guid, jobAction.Job.Name, jobAction.Job.Guid, $"Job deleted due to RML '{SelectedRML.Name}' being removed."); + await jobAction.Job.DeleteCascadeAsync(db); + } + else if (jobAction.Action == RmlDeleteDialogViewVM.RmlDeleteJobAction.Change) + { + var job = await db.Jobs.SingleOrDefaultAsync(x => x.Guid == jobAction.Job.Guid); + job.RmlGuid = jobAction.TargetRml.Guid; + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.JobSaved, _authentication.CurrentUser.Guid, jobAction.Job.Name, jobAction.Job.Guid, $"Job RML changed to '{jobAction.TargetRml.Name}' due to RML '{SelectedRML.Name}' being removed."); + } + } + + await db.SaveChangesAsync(); + } } await SelectedRML.DeleteCascadeAsync(_rmls_context); - _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlDeleted, _authentication.CurrentUser, SelectedRML.Name, SelectedRML, "RML deleted from Machine Studio."); LoadRmls(); } catch (Exception ex) { - LogManager.Log(ex, $"Error removing selected RML {SelectedRML.Name}."); - _notification.ShowError($"An error occurred while trying to remove the selected RML.\n{ex.Message}"); + LogManager.Log(ex, $"Error removing selected RML {SelectedRML?.Name}."); + _notification.ShowError($"An error occurred while trying to remove the selected RML.\n{ex.FlattenMessage()}"); + LoadRmls(); + } + finally + { + IsFree = true; } } - - IsFree = true; } } @@ -641,6 +731,11 @@ namespace Tango.MachineStudio.RML.ViewModels ActiveProcessParametersTableView.Refresh(); } + private void OnRMLFilterChanged() + { + RmlsCollectionView.Refresh(); + } + private void RemoveLiquidFactor(LiquidTypesRml liquidFactor) { if (_notification.ShowQuestion("Removing this liquid factor will remove the liquid type association with the RML and will drop the calibration data. Are you sure?")) @@ -788,6 +883,12 @@ namespace Tango.MachineStudio.RML.ViewModels String file = GetCCTFileOpen(); if (file != null) { + if (CCTS.ToList().Exists(x => x.FileName == Path.GetFileName(file))) + { + _notification.ShowError("The selected CCT file already exists on the database. Please select the CCT file from the dropdown box."); + return; + } + CctModel cctModel = new CctModel(); cctModel.Guid = Guid.NewGuid().ToString(); cctModel.IsNew = true; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/RmlDeleteDialogViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/RmlDeleteDialogViewVM.cs new file mode 100644 index 000000000..b4c6c6274 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/RmlDeleteDialogViewVM.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core; +using Tango.SharedUI; + +namespace Tango.MachineStudio.RML.ViewModels +{ + public class RmlDeleteDialogViewVM : DialogViewVM + { + public enum RmlDeleteJobAction + { + Delete, + Change + } + + public class RmlDeleteJob : ExtendedObject + { + public Job Job { get; set; } + public Machine Machine { get; set; } + private RmlDeleteJobAction _action; + + public RmlDeleteJobAction Action + { + get { return _action; } + set { _action = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(IsDelete)); } + } + + public bool IsDelete + { + get { return Action == RmlDeleteJobAction.Delete; } + } + + + public Rml TargetRml { get; set; } + + public override string ToString() + { + return $"{Machine.SerialNumber} => {Job.Name} => {Action} {(Action == RmlDeleteJobAction.Change ? $" => {TargetRml.Name}" : String.Empty)}"; + } + } + + private List<Job> _jobsToDelete; + + private List<RmlDeleteJob> _jobsActions; + public List<RmlDeleteJob> JobsActions + { + get { return _jobsActions; } + set { _jobsActions = value; RaisePropertyChangedAuto(); } + } + + public Rml Rml { get; set; } + + public List<Rml> Rmls { get; set; } + + public List<RmlDeleteJobAction> Actions { get; set; } + + public RmlDeleteDialogViewVM(Rml rml, List<Rml> rmls, List<Job> jobsToDelete) + { + Rml = rml; + Rmls = rmls.Where(x => x.Guid != rml.Guid).ToList(); + _jobsToDelete = jobsToDelete; + JobsActions = new List<RmlDeleteJob>(); + + Actions = new List<RmlDeleteJobAction>() + { + RmlDeleteJobAction.Delete, + RmlDeleteJobAction.Change + }; + } + + public override void OnShow() + { + base.OnShow(); + + List<RmlDeleteJob> list = new List<RmlDeleteJob>(); + + foreach (var job in _jobsToDelete) + { + RmlDeleteJob deleteJob = new RmlDeleteJob(); + deleteJob.Job = job; + deleteJob.Action = RmlDeleteJobAction.Delete; + deleteJob.Machine = job.Machine; + deleteJob.TargetRml = Rmls.FirstOrDefault(x => x.Guid != Rml.Guid); + + list.Add(deleteJob); + } + + JobsActions = list; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ColorCalibrationView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ColorCalibrationView.xaml new file mode 100644 index 000000000..116500f80 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ColorCalibrationView.xaml @@ -0,0 +1,213 @@ +<UserControl x:Class="Tango.MachineStudio.RML.Views.ColorCalibrationView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:vm="clr-namespace:Tango.MachineStudio.RML.ViewModels" + xmlns:global="clr-namespace:Tango.MachineStudio.RML" + xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:oxy="http://oxyplot.org/wpf" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + mc:Ignorable="d" + d:DesignHeight="450" d:DesignWidth="1200" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + + <UserControl.Resources> + <converters:EmptyStringToNullConverter x:Key="EmptyStringToNullConverter" /> + <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> + <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter"/> + </UserControl.Resources> + + <Grid> + <DockPanel> + <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="20 10"> + <TextBlock FontSize="16" HorizontalAlignment="Left" VerticalAlignment="Center">Liquid Type:</TextBlock> + <ComboBox Margin="40 0 0 0" MinWidth="180" HorizontalAlignment="Left" ItemsSource="{Binding LiquidTypes}" + SelectedItem="{Binding LiquidType}" DisplayMemberPath="Name" + Style="{StaticResource TransparentComboBoxStyle}" FontSize="16"></ComboBox> + </StackPanel> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="1.1*"/> + <ColumnDefinition Width="*"/> + </Grid.ColumnDefinitions> + <DockPanel Grid.Column="0"> + <Border DockPanel.Dock="Top" Background="{StaticResource TransparentBackgroundBrush200}" Margin="20 0 0 0 " Padding="5" CornerRadius="5" Height="40" VerticalAlignment="Top"> + <Border.Effect> + <DropShadowEffect Opacity="0.4" /> + </Border.Effect> + <Grid> + <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Margin="20 4 0 0" FontSize="16" Padding="0">LIQUID FACTOR</TextBlock> + </Grid> + </Border> + <Grid Margin="10 20 0 10"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="1*"/> + <ColumnDefinition Width="1*"/> + </Grid.ColumnDefinitions> + <Grid.RowDefinitions> + <RowDefinition Height="1*"/> + <RowDefinition Height="Auto"/> + <RowDefinition Height="Auto"/> + </Grid.RowDefinitions> + + + <Grid HorizontalAlignment="Left" VerticalAlignment="Stretch" Grid.Column="0" Grid.Row="0" Margin="20 0 10 0"> + <StackPanel Orientation="Vertical"> + <Button HorizontalAlignment="Left" Padding="6" Width="120" Background="{StaticResource TransparentBackgroundBrush200}" Command="{Binding ImportDataCommand}" ToolTip="Import data to calculate Liquid factor." Margin="0 0 10 4" BorderBrush="{StaticResource TransparentBackgroundBrush200}"> + <TextBlock FontSize="14" Foreground="{StaticResource MainWindow.Foreground}">IMPORT DATA</TextBlock> + </Button> + <DataGrid HorizontalAlignment="Left" VerticalScrollBarVisibility ="Auto" MaxHeight="280" SelectionUnit="FullRow" BorderBrush="{StaticResource DarkGrayBrush }" BorderThickness="1" Background="{StaticResource TransparentBackgroundBrush}" AlternatingRowBackground="{StaticResource Transparent200}" AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="False" ItemsSource="{Binding Measurements}" Margin="0 0 0 50"> + <DataGrid.CellStyle> + <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + </Style> + </DataGrid.CellStyle> + <DataGrid.Resources> + <Style x:Key="CellNumericUpDown" TargetType="{x:Type mahapps:NumericUpDown}" BasedOn="{StaticResource {x:Type mahapps:NumericUpDown}}"> + <Setter Property="FrameworkElement.HorizontalAlignment" Value="Stretch"/> + <Setter Property="HorizontalContentAlignment" Value="Left"/> + <Setter Property="Background" Value="Transparent"/> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/> + <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/> + <Setter Property="Focusable" Value="false"/> + <Setter Property="IsHitTestVisible" Value="false"/> + <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/> + <Setter Property="FrameworkElement.VerticalAlignment" Value="Top"/> + <Setter Property="VerticalContentAlignment" Value="Center"/> + <Setter Property="FrameworkElement.MinHeight" Value="0"/> + <Setter Property="HideUpDownButtons" Value="true"/> + </Style> + <Style x:Key="EditableCellNumericUpDown" TargetType="{x:Type mahapps:NumericUpDown}" BasedOn="{StaticResource {x:Type mahapps:NumericUpDown}}"> + <Setter Property="FrameworkElement.HorizontalAlignment" Value="Stretch"/> + <Setter Property="HorizontalContentAlignment" Value="Left"/> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/> + <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/> + <Setter Property="FrameworkElement.VerticalAlignment" Value="Top"/> + <Setter Property="VerticalContentAlignment" Value="Center"/> + <Setter Property="FrameworkElement.MinHeight" Value="0"/> + </Style> + </DataGrid.Resources> + <DataGrid.Columns> + <mahapps:DataGridNumericUpDownColumn Header="Ink nl/cm" Minimum="0" Maximum="100000" Binding="{Binding Ink}" HideUpDownButtons="True" Width="1*" ElementStyle="{StaticResource CellNumericUpDown}" EditingElementStyle="{StaticResource EditableCellNumericUpDown}" /> + <mahapps:DataGridNumericUpDownColumn Header="L" Minimum="0" Maximum="100" Binding="{Binding L}" HideUpDownButtons="True" Width="1*" ElementStyle="{StaticResource CellNumericUpDown}" EditingElementStyle="{StaticResource EditableCellNumericUpDown}"/> + <mahapps:DataGridNumericUpDownColumn Header="A" Minimum="-128" Maximum="127" Binding="{Binding A}" HideUpDownButtons="True" Width="1*" ElementStyle="{StaticResource CellNumericUpDown}" EditingElementStyle="{StaticResource EditableCellNumericUpDown}" /> + <mahapps:DataGridNumericUpDownColumn Header="B" Minimum="-128" Maximum="127" Binding="{Binding B}" HideUpDownButtons="True" Width="1*" ElementStyle="{StaticResource CellNumericUpDown}" EditingElementStyle="{StaticResource EditableCellNumericUpDown}" /> + </DataGrid.Columns> + </DataGrid> + + </StackPanel> + </Grid> + + <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="1" Grid.Row="0" Margin="10 0 0 0"> + <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderThickness="0" BorderBrush="{StaticResource DarkGrayBrush}" CornerRadius="5"> + <oxy:Plot Title="{Binding LiquidTypeName}" TitleFontSize="14" x:Name="CalibrationPlot" Margin="0 0 10 0" Background="Transparent" > + <oxy:Plot.Series > + <oxy:LineSeries ItemsSource="{Binding Points}" Color="#73B6EC" MarkerFill="SteelBlue" MarkerType="Circle" /> + <oxy:LineSeries ItemsSource="{Binding TargetPoints}" Color="#E14141" /> + </oxy:Plot.Series> + <oxy:Plot.Axes> + <oxy:LinearAxis Position="Bottom" Title = "nl/cm" MajorGridlineStyle="Solid" MinorGridlineStyle="Dot" IsZoomEnabled="True" /> + <oxy:LinearAxis Position="Left" Title = "Lab" MajorGridlineStyle="Solid" MinorGridlineStyle="Dot" IsZoomEnabled="True" Minimum="{Binding From}" Maximum="{Binding To}" /> + </oxy:Plot.Axes> + </oxy:Plot> + </Border> + </Grid> + + <Border Grid.Row="1" Grid.ColumnSpan="2" BorderBrush="{StaticResource BlueBrush100}" BorderThickness="0" CornerRadius="5" Margin="20 0 20 0"> + <StackPanel Orientation="Vertical" Grid.Row="0" Margin="2 5 0 0"> + <Border BorderThickness="0.5" CornerRadius="4" BorderBrush="{StaticResource DarkGrayBrush}" Visibility="{Binding HasError, Converter={StaticResource BooleanToVisibilityInverseConverter}}" Height="Auto" Margin="0 6 0 0"> + <TextBlock FontSize="16" Foreground="{StaticResource MainWindow.Foreground}" FontWeight="SemiBold" Visibility="{Binding HasError, Converter={StaticResource BooleanToVisibilityInverseConverter}}" Margin="10" > + <Run FontSize="16"> Factor: </Run> + <Run Text="{Binding Factor,StringFormat='#.0000'}" Foreground="{StaticResource BlueBrush100}"></Run> + </TextBlock> + </Border> + + <Border BorderThickness="0.5" CornerRadius="4" BorderBrush="{StaticResource DarkGrayBrush}" Visibility="{Binding HasError, Converter={StaticResource BooleanToVisibilityConverter}}" Height="Auto" Margin="0 6 0 0"> + <TextBlock FontSize="16" Foreground="{StaticResource MainWindow.Foreground}" FontWeight="SemiBold" Visibility="{Binding HasError, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="10" > + <Run FontSize="14"> Warning: </Run> + <Run Foreground="{StaticResource RedBrush300}" Text="{Binding ErrorMessage}" ></Run> + </TextBlock> + </Border> + </StackPanel> + </Border> + <Button Grid.Row="2" Grid.Column="1" Margin="0 20 20 0" VerticalAlignment="Bottom" HorizontalAlignment="Right" Background="{StaticResource TransparentBackgroundBrush200}" MinWidth="160" BorderBrush="{StaticResource TransparentBackgroundBrush200}" Command="{Binding CreateGraphCommand}" > + <TextBlock FontSize="14" Foreground="{StaticResource MainWindow.Foreground}">GET LIQUID FACTOR</TextBlock> + </Button> + </Grid> + </DockPanel> + <DockPanel Grid.Column="1"> + <Border DockPanel.Dock="Top" Background="{StaticResource TransparentBackgroundBrush200}" Margin="20 0 0 0 " Padding="5" CornerRadius="5" Height="40" VerticalAlignment="Top"> + <Border.Effect> + <DropShadowEffect Opacity="0.4" /> + </Border.Effect> + <Grid> + <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Margin="20 4 0 0" FontSize="16" Padding="0">LINEARIZATION</TextBlock> + </Grid> + </Border> + <Grid Margin="10 20 20 10"> + <Grid.RowDefinitions> + <RowDefinition Height="1*"/> + <RowDefinition Height="Auto"/> + </Grid.RowDefinitions> + <Grid Grid.Column="0" Margin="10 0 0 0"> + <Grid.RowDefinitions> + <RowDefinition Height="1*"/> + <RowDefinition Height="Auto"/> + </Grid.RowDefinitions> + <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Margin="0 0 0 0"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="1*"></ColumnDefinition> + <ColumnDefinition Width="1*"></ColumnDefinition> + </Grid.ColumnDefinitions> + + <Border Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderThickness="0" BorderBrush="{StaticResource DarkGrayBrush}" CornerRadius="5"> + <oxy:Plot Title="{Binding LiquidTypeName}" TitleFontSize="14" x:Name="LABLinearizationPlot" Margin="0 0 10 0" Background="Transparent" LegendPlacement="Inside" LegendPosition="TopRight" LegendOrientation="Vertical" LegendFontSize="9" LegendItemAlignment="Left" LegendLineSpacing="3" Foreground="{StaticResource Dialog.Foreground}"> + <oxy:Plot.Series > + <oxy:LineSeries ItemsSource="{Binding LPoints}" Color="LawnGreen" Title="L" StrokeThickness="1.5"/> + <oxy:LineSeries ItemsSource="{Binding APoints}" Color="#E14141" Title="A" StrokeThickness="1.5"/> + <oxy:LineSeries ItemsSource="{Binding BPoints}" Color="#73B6EC" Title="B" StrokeThickness="1.5"/> + </oxy:Plot.Series> + <oxy:Plot.Axes> + <oxy:LinearAxis Position="Bottom" Title = "Ink%" MajorGridlineStyle="Solid" MinorGridlineStyle="Dot" IsZoomEnabled="True" AxisTitleDistance ="12" Minimum="0" Maximum="100" /> + <oxy:LinearAxis Position="Left" Title = "LAB" MajorGridlineStyle="Solid" MinorGridlineStyle="Dot" IsZoomEnabled="True" Minimum="{Binding LabMinVal}" Maximum="{Binding LabMaxVal}" MinorStep="10" /> + </oxy:Plot.Axes> + </oxy:Plot> + </Border> + + <Border Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0" BorderThickness="0" BorderBrush="{StaticResource DarkGrayBrush}" CornerRadius="5" > + <oxy:Plot Title="{Binding LiquidTypeName}" TitleFontSize="14" x:Name="LinearizationPlot" Margin="0 0 0 0" Background="Transparent" LegendPlacement="Inside" LegendPosition="RightTop" LegendOrientation="Vertical" > + <oxy:Plot.Series > + <oxy:LineSeries ItemsSource="{Binding LinearizationPoints}" Color="#73B6EC" MarkerFill="SteelBlue" MarkerType="Circle"/> + </oxy:Plot.Series> + <oxy:Plot.Axes> + <oxy:LinearAxis Position="Bottom" Title = "In Ink" MajorGridlineStyle="Solid" MinorGridlineStyle="Dot" IsZoomEnabled="True" Minimum="0" Maximum="100"/> + <oxy:LinearAxis Position="Left" Title = "Out Ink" MajorGridlineStyle="Solid" MinorGridlineStyle="Dot" IsZoomEnabled="True" Minimum="0" Maximum="100"/> + </oxy:Plot.Axes> + </oxy:Plot> + </Border> + </Grid> + <StackPanel Orientation="Horizontal" Grid.Row="1" Margin="0 20 10 0" HorizontalAlignment="Right"> + <Button Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource TransparentBackgroundBrush200}" Padding="6" MinWidth="130" Command="{Binding ApplyCalibrationDataCommand}" ToolTip="Apply the calibration data to the current RML calibration tables."> + <TextBlock FontSize="14" Foreground="{StaticResource MainWindow.Foreground}">APPLY TO RML</TextBlock> + </Button> + <Button Margin="20 0 0 0" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource TransparentBackgroundBrush200}" Padding="6" ToolTip="Export to excel" MinWidth="130" Command="{Binding ExportGraphCommand}"> + <TextBlock FontSize="14" Foreground="{StaticResource MainWindow.Foreground}">EXPORT TO FILE</TextBlock> + </Button> + <Button Margin="20 0 0 0" VerticalAlignment="Bottom" HorizontalAlignment="Right" Background="{StaticResource TransparentBackgroundBrush200}" MinWidth="180" BorderBrush="{StaticResource TransparentBackgroundBrush200}" Command="{Binding CreateLinearizationGraphCommand}" > + <TextBlock FontSize="14" Foreground="{StaticResource MainWindow.Foreground}">CREATE LINEARIZATION GRAPH</TextBlock> + </Button> + </StackPanel> + </Grid> + + </Grid> + </DockPanel> + </Grid> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ColorCalibrationView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ColorCalibrationView.xaml.cs new file mode 100644 index 000000000..c29bb68fb --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ColorCalibrationView.xaml.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.MachineStudio.RML.ViewModels; + +namespace Tango.MachineStudio.RML.Views +{ + /// <summary> + /// Interaction logic for ColorCalibrationView.xaml + /// </summary> + public partial class ColorCalibrationView : UserControl + { + public ColorCalibrationView() + { + InitializeComponent(); + this.Loaded += ColorCalibrationView_Loaded; + } + + private void ColorCalibrationView_Loaded(object sender, RoutedEventArgs e) + { + if(DataContext is ColorCalibrationViewVM) + { + ColorCalibrationViewVM vm = (ColorCalibrationViewVM)DataContext; + vm.PlotControl = CalibrationPlot; + vm.LinearizationPlotControl = LinearizationPlot; + vm.LABLinearizationPlotControl = LABLinearizationPlot; + vm.Loading(); + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlDeleteDialogView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlDeleteDialogView.xaml new file mode 100644 index 000000000..7745848c1 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlDeleteDialogView.xaml @@ -0,0 +1,82 @@ +<UserControl x:Class="Tango.MachineStudio.RML.Views.RmlDeleteDialogView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:vm="clr-namespace:Tango.MachineStudio.RML.ViewModels" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:local="clr-namespace:Tango.MachineStudio.RML.Views" + mc:Ignorable="d" + d:DesignHeight="400" d:DesignWidth="700" Height="600" Width="900" Background="{StaticResource Dialog.Background}" d:DataContext="{d:DesignInstance Type=vm:RmlDeleteDialogViewVM, IsDesignTimeCreatable=False}" Foreground="{StaticResource Dialog.Foreground}"> + + <UserControl.Resources> + <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter" /> + </UserControl.Resources> + + <Grid Margin="10"> + <DockPanel> + <Grid DockPanel.Dock="Top"> + <StackPanel Orientation="Horizontal"> + <Grid> + <materialDesign:PackIcon Kind="Alert" Foreground="{StaticResource OrangeBrush}" Width="42" Height="42" /> + </Grid> + <TextBlock Margin="20 0 0 0" VerticalAlignment="Center" FontSize="22"> + <Run>DELETE</Run> + <Run></Run> + <Run Text="{Binding Rml.Name}"></Run> + </TextBlock> + </StackPanel> + </Grid> + + <Grid DockPanel.Dock="Bottom"> + <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" DockPanel.Dock="Bottom"> + <Button Command="{Binding CloseCommand}" Width="140" Height="40" Margin="0 0 10 0"> + CANCEL + </Button> + <Button Command="{Binding OKCommand}" IsDefault="True" Width="140" Height="40"> + DELETE + </Button> + </StackPanel> + </Grid> + + <Grid> + <DockPanel Margin="0 10 0 0"> + <TextBlock DockPanel.Dock="Top" Margin="5"> + <Run>The following jobs must be removed or change thread type before the selected thread can be deleted.</Run> + </TextBlock> + <DataGrid Margin="0 10 0 10" SelectionUnit="FullRow" SelectionMode="Single" ItemsSource="{Binding JobsActions}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False"> + <DataGrid.Columns> + <DataGridTextColumn Header="MACHINE" Width="Auto" Binding="{Binding Machine.SerialNumber}" IsReadOnly="True" /> + <DataGridTextColumn Header="JOB" Width="200" Binding="{Binding Job.Name}" IsReadOnly="True" /> + <DataGridComboBoxColumn Header="ACTION" Width="100" SelectedItemBinding="{Binding Action}"> + <DataGridComboBoxColumn.ElementStyle> + <Style TargetType="{x:Type ComboBox}"> + <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Actions, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" /> + </Style> + </DataGridComboBoxColumn.ElementStyle> + <DataGridComboBoxColumn.EditingElementStyle> + <Style TargetType="{x:Type ComboBox}"> + <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Actions, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" /> + </Style> + </DataGridComboBoxColumn.EditingElementStyle> + </DataGridComboBoxColumn> + <DataGridComboBoxColumn Header="TARGET RML" SelectedItemBinding="{Binding TargetRml}" Width="1*" DisplayMemberPath="Name"> + <DataGridComboBoxColumn.ElementStyle> + <Style TargetType="{x:Type ComboBox}"> + <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Rmls, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" /> + </Style> + </DataGridComboBoxColumn.ElementStyle> + <DataGridComboBoxColumn.EditingElementStyle> + <Style TargetType="{x:Type ComboBox}"> + <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Rmls, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" /> + </Style> + </DataGridComboBoxColumn.EditingElementStyle> + </DataGridComboBoxColumn> + </DataGrid.Columns> + </DataGrid> + </DockPanel> + </Grid> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlDeleteDialogView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlDeleteDialogView.xaml.cs new file mode 100644 index 000000000..96254c03a --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlDeleteDialogView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.MachineStudio.RML.Views +{ + /// <summary> + /// Interaction logic for RmlDeleteDialogView.xaml + /// </summary> + public partial class RmlDeleteDialogView : UserControl + { + public RmlDeleteDialogView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml index f425f2003..b6c91f066 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlView.xaml @@ -30,7 +30,7 @@ <Button Style="{StaticResource MaterialDesignFlatButton}" Height="Auto" Command="{Binding BackToRmlsCommand}"> <materialDesign:PackIcon Kind="ArrowLeft" Width="50" Height="50" Foreground="{StaticResource DarkGrayBrush200}" ToolTip="Back to RML list" /> </Button> - <TextBlock Text="{Binding ActiveRML.Name}" VerticalAlignment="Center" Margin="10 0 0 0" FontSize="34"></TextBlock> + <TextBlock MaxWidth="350" Text="{Binding ActiveRML.Name}" VerticalAlignment="Center" Margin="10 0 0 0" FontSize="30" TextWrapping="Wrap"></TextBlock> </StackPanel> <Button HorizontalAlignment="Right" Width="170" Height="45" Margin="0 0 20 0" VerticalAlignment="Center" Command="{Binding SaveCommand}"> @@ -214,7 +214,9 @@ </UniformGrid> <TextBlock Margin="0 40 0 0" Text="Color Conversion Version:" HorizontalAlignment="Center"></TextBlock> - <mahapps:NumericUpDown Minimum="1" Maximum="3" Value="{Binding ActiveRML.ColorConversionVersion}" HorizontalContentAlignment="Center" Background="Transparent" BorderBrush="{StaticResource DimGrayBrush}" HasDecimals="False" Margin="0 5 0 0" /> + <mahapps:NumericUpDown Minimum="1" Maximum="4" Value="{Binding ActiveRML.ColorConversionVersion}" HorizontalContentAlignment="Center" Background="Transparent" BorderBrush="{StaticResource DimGrayBrush}" HasDecimals="False" Margin="0 5 0 0" /> + + <CheckBox ToolTip="Use the color conversion engine to generate gradients" IsChecked="{Binding ActiveRML.UseColorLibGradients}" HorizontalAlignment="Center" Margin="0 40 0 0">Enable Gradient Generation</CheckBox> </StackPanel> </StackPanel> </Grid> @@ -226,6 +228,9 @@ <TabItem Header="SPOOLS" Margin="-100 0 0 0" mahapps:ControlsHelper.HeaderFontSize="20"> <local:SpoolsView/> </TabItem> + <TabItem Header="COLOR CALIBRATION" Margin="-100 0 0 0" mahapps:ControlsHelper.HeaderFontSize="20"> + <local:ColorCalibrationView DataContext="{Binding ColorCalibrationVM}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/> + </TabItem> </TabControl> </Grid> <Grid Grid.Row="1"> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlsView.xaml index 288f00a3d..b1a1f4aa5 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlsView.xaml @@ -18,10 +18,14 @@ <converters:ColorToIntegerConverter x:Key="ColorToIntegerConverter"></converters:ColorToIntegerConverter> </UserControl.Resources> - <Grid> + <Grid IsEnabled="{Binding IsFree}"> <DockPanel Margin="100 100 100 50" MaxWidth="1200"> <Grid DockPanel.Dock="Top"> <Image Source="../Images/threads.png" Width="300" Margin="10" /> + <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0 0 10 30"> + <materialDesign:PackIcon Kind="Magnify" Width="26" Height="26"/> + <TextBox Width="300" materialDesign:HintAssist.Hint="Search by name" Text="{Binding RMLFilter,UpdateSourceTrigger=PropertyChanged,Delay=500}"></TextBox> + </StackPanel> </Grid> <Grid DockPanel.Dock="Bottom"> <StackPanel> @@ -74,7 +78,7 @@ </StackPanel> </Grid> <Grid> - <DataGrid Margin="0 0 0 10" BorderBrush="Silver" IsReadOnly="True" BorderThickness="1" Background="{StaticResource TransparentBackgroundBrush}" AlternatingRowBackground="{StaticResource Transparent200}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{Binding Rmls}" SelectedItem="{Binding SelectedRML}"> + <DataGrid Margin="0 0 0 10" BorderBrush="Silver" IsReadOnly="True" BorderThickness="1" RowHeight="60" Background="{StaticResource TransparentBackgroundBrush}" AlternatingRowBackground="{StaticResource Transparent200}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{Binding Rmls}" SelectedItem="{Binding SelectedRML}"> <DataGrid.CellStyle> <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> <Setter Property="BorderThickness" Value="0"/> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs index 4cea7f69f..2d9a3cfd9 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs @@ -19,9 +19,13 @@ namespace Tango.MachineStudio.Statistics.Converters foreach(var val in colection) { string visibleText = val.ToString(); - if (val is bool) + if(val is bool && parameter is string) { - visibleText = (bool)val== true ? "Yes" : "No"; + string[] tokens = (parameter as string).Split(','); + if(tokens.Count() > 1) + { + visibleText = (bool)val == true ? tokens[1] : tokens[0]; + } } text.Append(visibleText); text.Append("/"); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidQuantityToFormatStringConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidQuantityToFormatStringConverter.cs new file mode 100644 index 000000000..3ab013ab3 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidQuantityToFormatStringConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + + +namespace Tango.MachineStudio.Statistics.Converters +{ + public class LiquidQuantityToFormatStringConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + string format = ""; + if (parameter is string) + { + format = (string)parameter; + } + + var longValue = System.Convert.ToUInt64(value.ToString()); + double liters_val = (longValue / 1000000000d); + double cc_val = (longValue / 1000000d); + double dispensers_val = (longValue / 130000000d); + string tooltip = String.Format($"Nanoliters: {longValue.ToString(format)}\nCubic Centimeters: {cc_val}\nLiters: {liters_val}\nDispensers: {dispensers_val}"); + return tooltip; + } + catch { } + + return ""; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/NanoLiterToLiterFormatConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/NanoLiterToLiterFormatConverter.cs index 32050cdb1..97f4ec066 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/NanoLiterToLiterFormatConverter.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/NanoLiterToLiterFormatConverter.cs @@ -16,7 +16,12 @@ namespace Tango.MachineStudio.Statistics.Converters { var longValue = System.Convert.ToUInt64(value.ToString()); double val = (longValue / 1000000000d); - return val.ToString("0.0"); + if (parameter is string) + { + string format= (string)parameter; + return val.ToString(format); + } + return val.ToString(); } catch { } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/TooltipLiquidQuantityFormatConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/TooltipLiquidQuantityFormatConverter.cs new file mode 100644 index 000000000..6c4d1347f --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/TooltipLiquidQuantityFormatConverter.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +namespace Tango.MachineStudio.Statistics.Converters +{ + class TooltipLiquidQuantityFormatConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + string format = ""; + if (parameter is string) + { + format = (string)parameter; + } + var longValue = System.Convert.ToUInt64(value.ToString()); + decimal liters_val = (decimal)(longValue / 1000000000d); + decimal cc_val = (decimal)(longValue / 1000000d); + decimal dispensers_val = (decimal)(longValue / 130000000d); + string tooltip = String.Format($"Nanoliters: {longValue.ToString(format)}\nCubic Centimeters: {cc_val}\nLiters: {liters_val}\nDispensers: {dispensers_val}"); + return tooltip; + } + catch { } + + return ""; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/ExcelModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/ExcelModel.cs new file mode 100644 index 000000000..f06b9fe60 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/ExcelModel.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Statistics.Models +{ + public class ExcelModel + { + public String ID { get; set; } + public String Machine { get; set; } + public String User { get; set; } + public String JobName { get; set; } + public String Thread { get; set; } + public String Length { get; set; } + public String Source { get; set; } + public String UploadDuration { get; set; } + public String HeatingDuration { get; set; } + public String StartTime { get; set; } + public String IsGradient { get; set; } + public String GR { get; set; } + public String Status { get; set; } + public String EndTime { get; set; } + public String EndPosition { get; set; } + public String Cyan { get; set; } + public String Magenta { get; set; } + public String Yellow { get; set; } + public String Black { get; set; } + public String Transparent { get; set; } + public String Lubricant { get; set; } + public String Cleaner { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj index f77dbd482..4ce0ea87d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj @@ -79,11 +79,14 @@ <Compile Include="Converters\CollectionConverter .cs" /> <Compile Include="Converters\DateTimeToStringFormatConverter.cs" /> <Compile Include="Converters\JobLengthConverter.cs" /> + <Compile Include="Converters\LiquidQuantityToFormatStringConverter.cs" /> <Compile Include="Converters\LiquidTypeToColorConverter.cs" /> <Compile Include="Converters\MidTankLevelToElementHeightConverter.cs" /> <Compile Include="Converters\NanoLiterToLiterFormatConverter.cs" /> <Compile Include="Converters\StringToBoolYesNoNullConverter.cs" /> <Compile Include="Converters\StringToFirstLetterConverter.cs" /> + <Compile Include="Converters\TooltipLiquidQuantityFormatConverter.cs" /> + <Compile Include="Models\ExcelModel.cs" /> <Compile Include="Models\TotalLiquidQuantityModel.cs" /> <Compile Include="Models\JobRunModel.cs" /> <Compile Include="Models\JobRunStatisticsModel.cs" /> @@ -94,6 +97,7 @@ <DependentUpon>PieChartTooltipControl.xaml</DependentUpon> </Compile> <Compile Include="StatisticsModule.cs" /> + <Compile Include="ValidationRules\DateExpiredRule.cs" /> <Compile Include="ViewModelLocator.cs" /> <Compile Include="ViewModels\ChartsViewVM.cs" /> <Compile Include="ViewModels\JobRunsViewVM.cs" /> @@ -172,6 +176,10 @@ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> <Name>Tango.Core</Name> </ProjectReference> + <ProjectReference Include="..\..\..\Tango.CSV\Tango.CSV.csproj"> + <Project>{58e8825f-0c96-449c-b320-1e82b0aa876b}</Project> + <Name>Tango.CSV</Name> + </ProjectReference> <ProjectReference Include="..\..\..\Tango.Logging\Tango.Logging.csproj"> <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> <Name>Tango.Logging</Name> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tooltips/PieChartTooltipControl.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tooltips/PieChartTooltipControl.xaml index 07f1308ec..b03f02249 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tooltips/PieChartTooltipControl.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tooltips/PieChartTooltipControl.xaml @@ -7,7 +7,7 @@ mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> - <Border Padding="10" Background="White" CornerRadius="5" BorderThickness="1" BorderBrush="Silver" MaxWidth="400"> + <Border Padding="10" Background="{StaticResource TransparentBackgroundBrush450}" CornerRadius="5" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" MaxWidth="400"> <TextBlock Text="{Binding Title}" TextWrapping="Wrap"></TextBlock> </Border> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ValidationRules/DateExpiredRule.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ValidationRules/DateExpiredRule.cs new file mode 100644 index 000000000..98b90f855 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ValidationRules/DateExpiredRule.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; + + +namespace Tango.MachineStudio.Statistics.ValidationRules +{ + public class DateExpiredRule : ValidationRule + { + public override ValidationResult Validate(object value, CultureInfo cultureInfo) + { + DateTime orderDate = (DateTime)value; + + return new ValidationResult(orderDate < DateTime.Now, "Please enter a date until today."); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs index 38c1cc24a..a98257086 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs @@ -49,30 +49,16 @@ namespace Tango.MachineStudio.Statistics.ViewModels public DateTime StartDate { get { return _startDate; } - set { _startDate = value; RaisePropertyChangedAuto();} + set { _startDate = value; RaisePropertyChangedAuto(); RaisePropertyChanged("EndDate"); } } private DateTime _endDate; public DateTime EndDate { get { return _endDate; } - set { _endDate = value; RaisePropertyChangedAuto();} + set { _endDate = value; RaisePropertyChangedAuto(); RaisePropertyChanged("StartDate"); } } - - private DateTime _minDate; - public DateTime MinDate - { - get { return _minDate; } - set { _minDate = value; RaisePropertyChangedAuto(); } - } - - private DateTime _maxDate; - public DateTime MaxDate - { - get { return _maxDate; } - set { _maxDate = value; RaisePropertyChangedAuto(); } - } - + public RelayCommand LoadJobRunsCommand { get; set; } #endregion @@ -85,41 +71,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels } #region Generate Charts - - //public async void Init() - //{ - //using (_notification.PushTaskItem("Loading statistics...")) - //{ - // IsFree = false; - - // await Task.Factory.StartNew(() => - // { - // _context = ObservablesContext.CreateDefault(); - // //_job_runs = _context.JobRuns.OrderBy(x => x.StartDate).ToList().Select(x => new JobRunStatisticsModel(x)).ToList(); - // //foreach (var run in _job_runs) - // //{ - // // run.LoadMachine(_context).GetAwaiter().GetResult(); - // //} - // }); - - // if (_job_runs.Count > 0) - // { - // MinDate = _job_runs.Min(x => x.StartDate); - // MaxDate = _job_runs.Max(x => x.StartDate); - // } - - // InvokeUIOnIdle(() => - // { - // if (_loaded) - // { - // OnDateRangeChanged(); - // } - // }); - - // _loaded = true; - // IsFree = true; - //} - //} + private async Task LoadJobRuns() { using (_notification.PushTaskItem("Loading statistics...")) @@ -127,25 +79,24 @@ namespace Tango.MachineStudio.Statistics.ViewModels try { IsFree = false; - + await Task.Factory.StartNew(() => { using (var db = ObservablesContext.CreateDefault()) { - _job_runs = db.JobRuns.OrderBy(x => x.StartDate).ToList().Select(x => new JobRunStatisticsModel(x)).ToList(); + DateTime startUtc = new DateTime(StartDate.Year, StartDate.Month, StartDate.Day, 0, 0, 0).ToUniversalTime(); + TimeSpan offsetTime = (EndDate.Date == DateTime.Now.Date) ? DateTime.Now.TimeOfDay : new TimeSpan(23, 59, 59); + DateTime endUtc = EndDate.ToUniversalTime() + offsetTime; + + _job_runs = db.JobRuns.Where(x => (x.StartDate <= endUtc && x.StartDate >= startUtc)).OrderBy(x => x.StartDate).ToList().Select(x => new JobRunStatisticsModel(x)).ToList(); + foreach (var run in _job_runs) { run.LoadMachine(db).GetAwaiter().GetResult(); } - } }); - if (_job_runs.Count > 0) - { - MinDate = _job_runs.Min(x => x.StartDate); - MaxDate = _job_runs.Max(x => x.StartDate); - } - + InvokeUIOnIdle(() => { if (_loaded) @@ -400,7 +351,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels #region Filter by Date public void OnDateRangeChanged() { - if (_job_runs != null && _job_runs.Count > 0)// && _loaded) + if (_job_runs != null)// && _job_runs.Count > 0)// && _loaded) { GenerateTimelineJobStatusChart(); GeneratePieFailedReasonsChart(); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs index 800346ff9..ae1592d8d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs @@ -21,9 +21,23 @@ using LiveCharts.Wpf; using LiveCharts; using Tango.BL.ValueObjects; using System.Diagnostics; +using Microsoft.Win32; +using Tango.CSV; +using System.ComponentModel; namespace Tango.MachineStudio.Statistics.ViewModels { + public enum HeadCleaningSelectionEnum + { + [Description("Exclude")] + Exclude = 0, + [Description("Include")] + Include = 1, + [Description("Only")] + Only = 2 + }; + + public class JobRunsViewVM : ViewModel { private INotificationProvider _notification; @@ -31,6 +45,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels private List<User> _allUsers; private List<RmlModel> _rmlsModels; + + #region Properties private ObservableCollection<JobRunModel> _jobRuns; @@ -83,7 +99,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels { get { return _startSelectedDate; } set { _startSelectedDate = value; - RaisePropertyChangedAuto(); } + RaisePropertyChangedAuto(); + } } private DateTime _endSelectedDate; @@ -172,6 +189,19 @@ namespace Tango.MachineStudio.Statistics.ViewModels } } + private HeadCleaningSelectionEnum _headCleaningSelected; + + public HeadCleaningSelectionEnum HeadCleaningSelected + { + get { return _headCleaningSelected; } + set + { + _headCleaningSelected = value; + RaisePropertyChangedAuto(); + } + } + + /// <summary> /// Gets or sets the JobRuns providers. /// </summary> @@ -200,12 +230,15 @@ namespace Tango.MachineStudio.Statistics.ViewModels public RelayCommand LoadJobRunsCommand { get; set; } + public RelayCommand ExportToExcelCommand { get; set; } + public JobRunsViewVM(INotificationProvider notificationProvider) { _notification = notificationProvider; JobRuns = new ObservableCollection<JobRunModel>(); LoadJobRunsCommand = new RelayCommand(async () => await LoadJobRuns(), () => IsFree); - LengthUpperValue = 5000.0; + ExportToExcelCommand = new RelayCommand(ExportToExcel, () => IsFree); + LengthUpperValue = 10000.0; LengthLowerValue = 0.0; DateTime now = DateTime.Now; StartSelectedDate = now.AddMonths(-1); @@ -250,6 +283,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels }); IsGradientSelection.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); IsGradientSelection.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); + + HeadCleaningSelected = HeadCleaningSelectionEnum.Exclude; + JobsProvider = new SuggestionProvider((filter) => { try @@ -305,8 +341,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels IsFree = true; } } + } - + /// <summary> /// Loads the job runs by filters. /// </summary> @@ -353,7 +390,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels x.BlackQuantity, x.TransparentQuantity, x.LubricantQuantity, - x.CleanerQuantity + x.CleanerQuantity, + x.IsHeadCleaning }); var machineIDs = new HashSet<string>(SelectedMachines.SynchedSource.ToList().Select(p => p.Guid)); if (machineIDs.Count > 0) @@ -375,6 +413,13 @@ namespace Tango.MachineStudio.Statistics.ViewModels { db_JobRuns = db_JobRuns.Where(x => isGradientArr.Contains(x.IsGradient)); } + + if(HeadCleaningSelected != HeadCleaningSelectionEnum.Include) + { + bool isHeadCleaning = HeadCleaningSelected == HeadCleaningSelectionEnum.Only; + db_JobRuns = db_JobRuns.Where(x => isHeadCleaning == x.IsHeadCleaning); + } + List<String> rmlGuids = SelectedThreads.SynchedSource.Select(y => y.Guid).ToList(); if (rmlGuids != null && rmlGuids.Count > 0) { @@ -415,7 +460,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels BlackQuantity = x.BlackQuantity, TransparentQuantity = x.TransparentQuantity, LubricantQuantity = x.LubricantQuantity, - CleanerQuantity = x.CleanerQuantity + CleanerQuantity = x.CleanerQuantity, + IsHeadCleaning = x.IsHeadCleaning }).ToList(); var modelList = runs.Select(x => new JobRunModel() @@ -444,12 +490,91 @@ namespace Tango.MachineStudio.Statistics.ViewModels } } - #region GenerateS_StatisticsValueCollection + private void ExportToExcel() + { + SaveFileDialog dlg = new SaveFileDialog(); + dlg.Title = "Job Runs Statistic Report"; + dlg.Filter = "CSV Files|*.csv"; + dlg.FileName = $"Statistics_Job_runs"; + dlg.DefaultExt = ".csv"; + if (dlg.ShowDialog().Value) + { + try + { + CsvFile<ExcelModel> csvFile = new CsvFile<ExcelModel>(new CsvDestination(dlg.FileName), new CsvDefinition() + { + Columns = new List<String>() + { + "ID", + "Machine", + "User", + "Job Name", + "Thread", + "Length", + "Source", + "Upload Duration", + "Heating Duration", + "Start Time", + "IsGradient", + "Gradient Resolution", + "Status", + "End Date", + "End Position", + "Cyan", + "Magenta", + "Yellow", + "Black", + "Transparent", + "Lubricant", + "Cleaner" + }, + }); + var selection = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.JobRun.EndDate != null && z.JobRun.ActualStartDate != null); + foreach (var jobRunModel in selection) + { + ExcelModel excel_model = new ExcelModel(); + excel_model.ID = jobRunModel.JobRun.ID.ToString(); + excel_model.Machine = jobRunModel.Machine != null ? jobRunModel.Machine.SerialNumber : ""; + excel_model.User = jobRunModel.User != null ? jobRunModel.User.Contact.FullName: ""; + excel_model.JobName = jobRunModel.JobRun.JobName; + excel_model.Thread = jobRunModel.Rml != null ? jobRunModel.Rml.Name : ""; + excel_model.Length = String.Format("{0:0.##}", jobRunModel.JobRun.JobLength); + excel_model.Source = jobRunModel.JobRun.Source.ToString(); + excel_model.UploadDuration = jobRunModel.UploadDuration != null ? ((TimeSpan)(jobRunModel.UploadDuration)).ToString(@"hh\:mm\:ss") : TimeSpan.FromSeconds(0).ToString(@"hh\:mm\:ss"); + excel_model.HeatingDuration = jobRunModel.HeatingDuration != null ? ((TimeSpan)(jobRunModel.HeatingDuration)).ToString(@"hh\:mm\:ss") : TimeSpan.FromSeconds(0).ToString(@"hh\:mm\:ss"); + excel_model.StartTime = jobRunModel.JobRun.ActualStartDate != null ? ((DateTime)jobRunModel.JobRun.ActualStartDate).ToLocalTime().ToString("MM/dd/yy HH:mm"): ""; + excel_model.IsGradient = jobRunModel.JobRun.IsGradient ? "Yes" : "No"; + excel_model.GR = jobRunModel.JobRun.GradientResolutionCm.ToString(); + excel_model.Status = jobRunModel.JobRun.JobRunStatus.ToString(); + excel_model.EndTime = jobRunModel.JobRun.EndDate != null ? ((DateTime)jobRunModel.JobRun.EndDate).ToLocalTime().ToString("MM/dd/yy HH:mm"): ""; + excel_model.EndPosition = String.Format("{0:0.##}", jobRunModel.JobRun.EndPosition); + excel_model.Cyan = jobRunModel.JobRun.CyanQuantity < 0 ? "" :jobRunModel.JobRun.CyanQuantity.ToString(); + excel_model.Magenta = jobRunModel.JobRun.MagentaQuantity < 0 ? "" : jobRunModel.JobRun.MagentaQuantity.ToString(); + excel_model.Yellow = jobRunModel.JobRun.YellowQuantity < 0 ? "" : jobRunModel.JobRun.YellowQuantity.ToString(); + excel_model.Black = jobRunModel.JobRun.BlackQuantity < 0 ? "" : jobRunModel.JobRun.BlackQuantity.ToString(); + excel_model.Transparent = jobRunModel.JobRun.TransparentQuantity < 0 ? "" : jobRunModel.JobRun.TransparentQuantity.ToString(); + excel_model.Lubricant = jobRunModel.JobRun.LubricantQuantity < 0 ? "" : jobRunModel.JobRun.LubricantQuantity.ToString(); + excel_model.Cleaner = jobRunModel.JobRun.CleanerQuantity < 0 ? "" : jobRunModel.JobRun.CleanerQuantity.ToString(); + csvFile.Append(excel_model); + + } - /// <summary> - /// Generates the statistics. - /// </summary> - protected void GenerateStatistics() + csvFile.Dispose(); + _notification.ShowInfo("Report generated successfully."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error generating Statistics Job Runs report."); + _notification.ShowError($"Error generating Statistics Job Runs report..\n{ex.Message}"); + } + } + } + #region GenerateS_StatisticsValueCollection + + /// <summary> + /// Generates the statistics. + /// </summary> + protected void GenerateStatistics() { StatisticsValueCollection.Clean(); if (JobRuns.Count() == 0) @@ -495,7 +620,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels average = selection.Average(x => (x.JobRun.EndDate - x.JobRun.ActualStartDate).Value.TotalMilliseconds); } StatisticsValueCollection.AddStatisticsValue("Total Dyeing Time", val, " hours"); - StatisticsValueCollection.AddStatisticsValue("Total Dyeing Time", Math.Max(TimeSpan.FromMilliseconds(average).TotalHours, 0), " hours"); + StatisticsValueCollection.AddStatisticsValue("Average Dyeing Time", Math.Max(TimeSpan.FromMilliseconds(average).TotalHours, 0), " hours"); } /// <summary> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml index ae4bf1d46..b76154941 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml @@ -6,6 +6,7 @@ xmlns:vm="clr-namespace:Tango.MachineStudio.Statistics.ViewModels" xmlns:global="clr-namespace:Tango.MachineStudio.Statistics" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:localrule="clr-namespace:Tango.MachineStudio.Statistics.ValidationRules" xmlns:local="clr-namespace:Tango.MachineStudio.Statistics.Views" xmlns:tooltips="clr-namespace:Tango.MachineStudio.Statistics.Tooltips" xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" @@ -21,14 +22,45 @@ <StackPanel Margin="60 20 0 0" VerticalAlignment="Center" HorizontalAlignment="Left" Orientation="Horizontal" DockPanel.Dock="Left"> <StackPanel> <TextBlock FontSize="10">Start Date:</TextBlock> - <DatePicker DisplayDateStart="{Binding MinDate}" DisplayDateEnd="{Binding MaxDate}" SelectedDate="{Binding StartDate}" materialDesign:HintAssist.Hint="Pick start date" Width="200" VerticalAlignment="Bottom" FontSize="16"></DatePicker> + <DatePicker x:Name="startdatePicker" SelectedDateChanged="StartDatePicker_SelectedDateChanged" materialDesign:HintAssist.Hint="Pick start date" Width="200" VerticalAlignment="Bottom" FontSize="16"> + <DatePicker.SelectedDate> + <Binding Path="StartDate" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> + <Binding.ValidationRules> + <localrule:DateExpiredRule x:Name="StartDateExpiredRule"/> + </Binding.ValidationRules> + </Binding> + </DatePicker.SelectedDate> + </DatePicker> </StackPanel> <StackPanel Margin="40 0 0 0"> <TextBlock FontSize="10">End Date:</TextBlock> - <DatePicker DisplayDateStart="{Binding MinDate}" DisplayDateEnd="{Binding MaxDate}" SelectedDate="{Binding EndDate}" materialDesign:HintAssist.Hint="Pick end date" Width="200" VerticalAlignment="Bottom" FontSize="16"></DatePicker> + <DatePicker x:Name="endDatePicker" materialDesign:HintAssist.Hint="Pick end date" Width="200" VerticalAlignment="Bottom" FontSize="16" SelectedDateChanged="EndDatePicker_SelectedDateChanged"> + <DatePicker.SelectedDate> + <Binding Path="EndDate" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> + <Binding.ValidationRules> + <localrule:DateExpiredRule x:Name="EndDateExpiredRule"/> + </Binding.ValidationRules> + </Binding> + </DatePicker.SelectedDate> + </DatePicker> </StackPanel> - <Button Width="100" Margin="60 0 0 0" Command="{Binding LoadJobRunsCommand}" VerticalAlignment="Bottom" HorizontalAlignment="Right">LOAD</Button> + <Button Width="100" Margin="60 0 0 0" Command="{Binding LoadJobRunsCommand}" VerticalAlignment="Bottom" HorizontalAlignment="Right" Content="LOAD"> + <Button.Style> + <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}"> + <Setter Property="IsEnabled" Value="False"/> + <Style.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding Path=(Validation.HasError), Source={x:Reference startdatePicker}}" Value="False"/> + <Condition Binding="{Binding Path=(Validation.HasError), Source={x:Reference endDatePicker}}" Value="False"/> + </MultiDataTrigger.Conditions> + <Setter Property="IsEnabled" Value="True"/> + </MultiDataTrigger> + </Style.Triggers> + </Style> + </Button.Style> + </Button> </StackPanel> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs index d79d88281..bd97ed2bc 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs @@ -31,5 +31,44 @@ namespace Tango.MachineStudio.Statistics.Views var tooltip = ((chartPoint.ChartView as PieChart).DataTooltip as Tooltips.PieChartTooltipControl).Title; txtPieTitle.Text = tooltip; } + private void StartDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) + { + DatePicker datePickerObj = sender as DatePicker; + if (datePickerObj != null && datePickerObj.SelectedDate != null && endDatePicker.SelectedDate != null) + { + if (datePickerObj.SelectedDate > endDatePicker.SelectedDate) + { + BindingExpression start_be = datePickerObj.GetBindingExpression(DatePicker.SelectedDateProperty); + ValidationError validationError = new ValidationError(StartDateExpiredRule, start_be); + validationError.ErrorContent = "The start time must be less than or equal to end time."; + Validation.MarkInvalid(start_be, validationError); + } + else if (Validation.GetHasError(endDatePicker)) + { + BindingExpression end_be = endDatePicker.GetBindingExpression(DatePicker.SelectedDateProperty); + Validation.ClearInvalid(end_be); + } + } + } + + private void EndDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) + { + DatePicker datePickerObj = sender as DatePicker; + if (datePickerObj.SelectedDate != null && startdatePicker.SelectedDate != null) + { + if (datePickerObj != null && datePickerObj.SelectedDate < startdatePicker.SelectedDate) + { + BindingExpression end_be = datePickerObj.GetBindingExpression(DatePicker.SelectedDateProperty); + ValidationError validationError = new ValidationError(EndDateExpiredRule, end_be); + validationError.ErrorContent = "The end time must be greater than or equal to the start time."; + Validation.MarkInvalid(end_be, validationError); + } + else if (Validation.GetHasError(startdatePicker)) + { + BindingExpression start_be = startdatePicker.GetBindingExpression(DatePicker.SelectedDateProperty); + Validation.ClearInvalid(start_be); + } + } + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml index 6431d72fb..bc99c1bfa 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml @@ -6,14 +6,17 @@ xmlns:sharedConverters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:localConverters="clr-namespace:Tango.MachineStudio.Statistics.Converters" + xmlns:localrule="clr-namespace:Tango.MachineStudio.Statistics.ValidationRules" xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" xmlns:autoComplete="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete" xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" xmlns:tooltips="clr-namespace:Tango.MachineStudio.Statistics.Tooltips" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:local="clr-namespace:Tango.MachineStudio.Statistics.Views" xmlns:model="clr-namespace:Tango.MachineStudio.Statistics.Models" + xmlns:vs="clr-namespace:Tango.MachineStudio.Statistics.ViewModels" xmlns:wellknowntypes="clr-namespace:Google.Protobuf.WellKnownTypes;assembly=Google.Protobuf" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="1800" Foreground="{StaticResource JobFieldForeground}"> @@ -30,6 +33,8 @@ <localConverters:MidTankLevelToElementHeightConverter x:Key="MidTankLevelToElementHeightConverter"/> <localConverters:JobLengthConverter x:Key="JobLengthConverter"/> <localConverters:NanoLiterToLiterFormatConverter x:Key="NanoLiterToLiterFormatConverter"/> + <localConverters:LiquidQuantityToFormatStringConverter x:Key="LiquidQuantityToFormatStringConverter"/> + <localConverters:TooltipLiquidQuantityFormatConverter x:Key="TooltipLiquidQuantityFormatConverter"/> <ResourceDictionary x:Key="SelectAllTextBoxResource"> <Style TargetType="TextBox"> @@ -38,6 +43,12 @@ </Style> </ResourceDictionary> + <ObjectDataProvider x:Key="HeadCleaning" MethodName="GetValues" ObjectType="{x:Type sys:Enum}"> + <ObjectDataProvider.MethodParameters> + <x:Type TypeName="vs:HeadCleaningSelectionEnum"/> + </ObjectDataProvider.MethodParameters> + </ObjectDataProvider> + <Style TargetType="{x:Type TextBlock}" x:Key="WrapText"> <Setter Property="TextWrapping" Value="Wrap"/> </Style> @@ -51,39 +62,23 @@ <Setter Property="Background" Value="Transparent"/> <Setter Property="LegendLocation" Value="None"/> </Style> - + <DataTemplate x:Key="PopUpDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}"> + <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" Click="CheckBox_StayChecked" Tag="{Binding Path=ItemsSource, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}},Mode=OneWay}"> <CheckBox.Content> <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data}"></TextBlock> </CheckBox.Content> </CheckBox> </DataTemplate> - <DataTemplate x:Key="PopUpSNDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" > - <CheckBox.Content> - <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data.SerialNumber}" ToolTip="{Binding Data.SerialNumber}" FontFamily="{StaticResource FontName}"></TextBlock> - </CheckBox.Content> - </CheckBox> - </DataTemplate> - <DataTemplate x:Key="PopupBoolDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}"> + <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" Click="CheckBox_StayChecked" Tag="{Binding Path=ItemsSource, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}},Mode=OneWay}"> <CheckBox.Content> <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data, Converter={StaticResource BooleanToYesNoConverter}}"/> </CheckBox.Content> </CheckBox> </DataTemplate> - <DataTemplate x:Key="PopupThreadDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" > - <CheckBox.Content> - <TextBlock Margin="5 0 5 0" VerticalAlignment="Center" Text="{Binding Data.Name}" ToolTip="{Binding Data.Name}" FontFamily="{StaticResource FontName}" FontSize="11"></TextBlock> - </CheckBox.Content> - </CheckBox> - </DataTemplate> - <Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}" BasedOn="{StaticResource MaterialDesignToolTip}"> <Setter Property="Background" Value="{StaticResource Logging.Background}" /> @@ -146,13 +141,18 @@ </DockPanel> </Border> <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> - <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="#F6F6F6" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> - <ScrollViewer MaxHeight="600" Background="#F6F6F6" > - <ItemsControl ItemsSource="{Binding SelectedMachines}" Foreground="{StaticResource MainWindow.Foreground}" ItemTemplate="{StaticResource PopUpSNDataTemplate}"/> - </ScrollViewer> + <controls:AllSelectedCheckboxList Style="{StaticResource AllSelectedCheckBoxListStyle}" MaxHeight="600" ItemsSource="{Binding SelectedMachines}" Background="{StaticResource ComboBox.Floating.Background}" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionMode="Multiple" AllSelected="True" FontSize="11" FontFamily="{StaticResource FontName}"> + <controls:AllSelectedCheckboxList.ItemTemplate> + <DataTemplate > + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data.SerialNumber}" ToolTip="{Binding Data.SerialNumber}" FontFamily="{StaticResource FontName}" Background="{DynamicResource TransparentBackgroundBrush}" FontSize="11"></TextBlock> + + </DataTemplate> + </controls:AllSelectedCheckboxList.ItemTemplate> + </controls:AllSelectedCheckboxList> </Border> </Popup> </Grid> @@ -161,13 +161,30 @@ </ToggleButton> </StackPanel> - <StackPanel Margin="50 10 0 0" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" HorizontalAlignment="Center"> <TextBlock FontSize="11">Start Date:</TextBlock> - <DatePicker x:Name="startdatePicker" Margin="0 5 0 0" SelectedDate="{Binding StartSelectedDate}" materialDesign:HintAssist.Hint="Pick start date" Width="130" VerticalAlignment="Center" FontSize="11" /> + <DatePicker x:Name="startdatePicker" SelectedDateChanged="StartDatePicker_SelectedDateChanged" Margin="0 5 0 0" materialDesign:HintAssist.Hint="Pick start date" Width="130" VerticalAlignment="Center" FontSize="11" > + <DatePicker.SelectedDate> + <Binding Path="StartSelectedDate" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> + <Binding.ValidationRules> + <localrule:DateExpiredRule x:Name="StartDateExpiredRule"/> + </Binding.ValidationRules> + </Binding> + </DatePicker.SelectedDate> + </DatePicker> </StackPanel> - <StackPanel Margin="50 10 0 0" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" HorizontalAlignment="Center"> <TextBlock FontSize="11">End Date:</TextBlock> - <DatePicker x:Name="endDatePicker" Margin="0 5 0 0" SelectedDate="{Binding EndSelectedDate}" materialDesign:HintAssist.Hint="Pick end date" Width="130" VerticalAlignment="Center" FontSize="11" /> + <DatePicker x:Name="endDatePicker" Margin="0 5 0 0" materialDesign:HintAssist.Hint="Pick end date" Width="130" VerticalAlignment="Center" FontSize="11" SelectedDateChanged="EndDatePicker_SelectedDateChanged"> + <DatePicker.SelectedDate> + <Binding Path="EndSelectedDate" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> + <Binding.ValidationRules> + <localrule:DateExpiredRule x:Name="EndDateExpiredRule"/> + </Binding.ValidationRules> + </Binding> + </DatePicker.SelectedDate> + + </DatePicker> </StackPanel> </StackPanel> @@ -184,7 +201,7 @@ </autoComplete:AutoCompleteTextBox.ItemTemplate> </autoComplete:AutoCompleteTextBox> </StackPanel> - <StackPanel Margin="50 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Source:" VerticalAlignment="Center" FontSize="11"></TextBlock> <ToggleButton Width="130" Height="24" Margin="0 10 0 0" x:Name="selectJobRunSources" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> <ToggleButton.Template> @@ -199,7 +216,7 @@ </DockPanel> </Border> <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> - <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="#F6F6F6" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> @@ -212,7 +229,7 @@ </ToggleButton.Template> </ToggleButton> </StackPanel> - <StackPanel Margin="50 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Gradient:" VerticalAlignment="Center" FontSize="11"></TextBlock> <ToggleButton Height="24" Width="130" Margin="0 10 0 0" x:Name="selectIsGradient" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> <ToggleButton.Template> @@ -224,12 +241,12 @@ <materialDesign:PackIcon Width="16" Height="16" Kind="ChevronDown" VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Right"/> </Button> <TextBlock VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" FontSize="11" Margin="5 0 2 0"> - <Run Text="{Binding IsGradientSelection.SynchedSource, Converter={StaticResource CollectionConverter}}"></Run> + <Run Text="{Binding IsGradientSelection.SynchedSource, Converter={StaticResource CollectionConverter}, ConverterParameter='No, Yes'}"></Run> </TextBlock> </DockPanel> </Border> <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> - <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="#F6F6F6" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}"> + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}"> <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> @@ -242,12 +259,12 @@ </ToggleButton.Template> </ToggleButton> </StackPanel> - <StackPanel Margin="40 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Length:" VerticalAlignment="Center" FontSize="11"></TextBlock> <Border BorderThickness="1" CornerRadius="3" BorderBrush="{StaticResource borderBrush}" Margin="0 10 0 0" Height="24" Padding="10 0"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding LengthLowerValue, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" FontSize="11" Width="30"></TextBlock> - <mahapps:RangeSlider Focusable="True" Height="40" Margin="5 5 5 5" Minimum="0" Maximum="5000" Width="140" ExtendedMode="True" + <mahapps:RangeSlider Focusable="True" Height="40" Margin="5 5 5 5" Minimum="0" Maximum="10000" Width="140" ExtendedMode="True" LowerValue="{Binding LengthLowerValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" UpperValue="{Binding LengthUpperValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" IsSnapToTickEnabled="True" FontSize="8"/> @@ -255,7 +272,7 @@ </StackPanel> </Border> </StackPanel> - <StackPanel Margin="40 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Status:" VerticalAlignment="Center" FontSize="11"></TextBlock> <ToggleButton Height="24" Width="170" Margin="0 10 0 0" x:Name="selectJobRunStatus" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> <ToggleButton.Template> @@ -270,7 +287,7 @@ </DockPanel> </Border> <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> - <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="#F6F6F6" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> @@ -282,9 +299,9 @@ </ToggleButton.Template> </ToggleButton> </StackPanel> - <StackPanel Margin="40 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Threads:" VerticalAlignment="Center" FontSize="11"></TextBlock> - <ToggleButton Width="140" Margin="0 10 0 0" x:Name="selectThreadsButton" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> + <ToggleButton Width="100" Margin="0 10 0 0" x:Name="selectThreadsButton" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> <ToggleButton.Template> <ControlTemplate> <Grid> @@ -313,10 +330,52 @@ <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> - <ScrollViewer MaxHeight="600" Background="#F6F6F6"> - <ItemsControl ItemsSource="{Binding SelectedThreads}" Foreground="{StaticResource MainWindow.Foreground}" ItemTemplate="{StaticResource PopupThreadDataTemplate}"/> - - </ScrollViewer> + <controls:AllSelectedCheckboxList Style="{StaticResource AllSelectedCheckBoxListStyle}" MaxHeight="600" ItemsSource="{Binding SelectedThreads}" Background="{StaticResource ComboBox.Floating.Background}" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionMode="Multiple" AllSelected="True" FontSize="11" FontFamily="{StaticResource FontName}"> + <controls:AllSelectedCheckboxList.ItemTemplate> + <DataTemplate > + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data.Name}" ToolTip="{Binding Data.Name}" FontFamily="{StaticResource FontName}"></TextBlock> + </DataTemplate> + </controls:AllSelectedCheckboxList.ItemTemplate> + </controls:AllSelectedCheckboxList> + </Border> + </Popup> + </Grid> + </ControlTemplate> + </ToggleButton.Template> + </ToggleButton> + </StackPanel> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <TextBlock Text="HeadCleaning:" VerticalAlignment="Center" FontSize="11"></TextBlock> + <ToggleButton Height="24" Width="120" Margin="0 10 0 0" x:Name="isHeadCleaningToggleButton" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> + <ToggleButton.Template> + <ControlTemplate> + <Grid> + <Border CornerRadius="3" BorderBrush="{StaticResource borderBrush}" BorderThickness="1" TextElement.Foreground="Black" > + <DockPanel> + <Button x:Name="IsHeadCleaningButton" Width="18" Padding="0" Height="16" DockPanel.Dock="Right" BorderBrush="{x:Null}" HorizontalAlignment="Left" Click="IsHeadCleaningButton_Click" Style="{StaticResource MaterialDesignFlatButton}" Foreground="{StaticResource MainWindow.Foreground}"> + <materialDesign:PackIcon Width="16" Height="16" Kind="ChevronDown" VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Right"/> + </Button> + <TextBlock VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" FontSize="11" Margin="5 0 2 0" Text="{Binding HeadCleaningSelected, Converter={StaticResource EnumToDescriptionConverter}}"> + + </TextBlock> + </DockPanel> + </Border> + <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}"> + <Border.Effect> + <DropShadowEffect Opacity="0.2" /> + </Border.Effect> + <ListBox x:Name="HeadCleaningListBoxItem" ItemsSource="{Binding Source={StaticResource HeadCleaning}}" Foreground="{StaticResource MainWindow.Foreground}" SelectedItem="{Binding HeadCleaningSelected, Mode=TwoWay}" SelectionMode="Single" > + <ListBox.ItemTemplate> + <DataTemplate> + <CheckBox x:Name="HeadCleaningCheckBox" Selector.IsSelected="True" VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, UpdateSourceTrigger=PropertyChanged}" Click="CheckBox_PreventUndoCheck"> + <CheckBox.Content> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Converter={StaticResource EnumToDescriptionConverter}}"/> + </CheckBox.Content> + </CheckBox> + </DataTemplate> + </ListBox.ItemTemplate> + </ListBox> </Border> </Popup> </Grid> @@ -326,7 +385,22 @@ </StackPanel> </StackPanel> </Grid> - <Button Grid.Column="1" HorizontalAlignment="Right" Command="{Binding LoadJobRunsCommand}" Margin="0 0 10 0" Padding="70 15" Height="Auto" VerticalAlignment="Center">ANALYZE</Button> + <Button Grid.Column="1" HorizontalAlignment="Right" Command="{Binding LoadJobRunsCommand}" Margin="0 0 10 0" Padding="30 15" Height="Auto" VerticalAlignment="Center" Content="ANALYZE"> + <Button.Style> + <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}"> + <Setter Property="IsEnabled" Value="False"/> + <Style.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding Path=(Validation.HasError), Source={x:Reference startdatePicker}}" Value="False"/> + <Condition Binding="{Binding Path=(Validation.HasError), Source={x:Reference endDatePicker}}" Value="False"/> + </MultiDataTrigger.Conditions> + <Setter Property="IsEnabled" Value="True"/> + </MultiDataTrigger> + </Style.Triggers> + </Style> + </Button.Style> + </Button> </Grid> </Border> </Grid> @@ -419,7 +493,7 @@ </DataGridTemplateColumn> <DataGridTextColumn Header="ID" Binding="{Binding JobRun.ID}" Width="50" ElementStyle="{StaticResource WrapText}"/> <DataGridTextColumn Header="Machine" Binding="{Binding Machine.SerialNumber}" Width="100" ></DataGridTextColumn> - <DataGridTextColumn Header="User" Binding="{Binding User.Contact.FullName}" Width="100" ElementStyle="{StaticResource WrapText}" /> + <DataGridTextColumn Header="User" Binding="{Binding User.Contact.FullName,TargetNullValue='PPC',FallbackValue='PPC'}" Width="100" ElementStyle="{StaticResource WrapText}" /> <DataGridTextColumn Header="Job Name" Binding="{Binding JobRun.JobName}" Width="100" ElementStyle="{StaticResource WrapText}"/> <DataGridTextColumn Header="Thread" Binding="{Binding Rml.Name}" Width="80" ElementStyle="{StaticResource WrapText}"/> <DataGridTextColumn Header="Length" Binding="{Binding JobRun.JobLength, StringFormat={}{0:0.00}}" Width="60" /> @@ -484,11 +558,11 @@ </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> - <DockPanel ToolTip="{Binding Quantity}" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="10"> - <Grid DockPanel.Dock="Top" Height="40" Margin="0 5 8 0" Width="16"> - <Border x:Name="LiquidTypeBorder" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" CornerRadius="2"> + <DockPanel ToolTip="{Binding Quantity, Converter={StaticResource TooltipLiquidQuantityFormatConverter}, ConverterParameter='#,#\\'}" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="10"> + <Grid DockPanel.Dock="Top" Height="40" Margin="0 5 8 0" Width="16" > + <Border x:Name="LiquidTypeBorder" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" CornerRadius="2" > <Canvas x:Name="LiquidCanvas" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0" ClipToBounds="True" ToolTip="{Binding Quantity}" ToolTipService.Placement="Left" ToolTipService.VerticalOffset="10"> - <Border Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualHeight }" Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualWidth }"> + <Border Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualHeight }" Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualWidth }" > <Border.Background> <SolidColorBrush Color="{Binding LiquidType,Converter={StaticResource LiquidTypeToColorConverter}}" /> </Border.Background> @@ -505,6 +579,7 @@ </Style> </Border.Style> </Border> + <Border Background="Transparent" ToolTip="{Binding Quantity, Converter={StaticResource TooltipLiquidQuantityFormatConverter}, ConverterParameter='#,#\\'}" Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualHeight }" Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualWidth }"></Border> </Canvas> </Border> </Grid> @@ -554,7 +629,7 @@ <StackPanel Orientation="Horizontal" Margin="0 3"> <TextBlock Text="{Binding Name}" FontWeight="SemiBold"/> <TextBlock Text=": "/> - <TextBlock Text="{Binding Value, StringFormat={}{0:#,0.##}}"/> + <TextBlock Text="{Binding Value, StringFormat={}{0:N2}}"/> <TextBlock Text="{Binding Unit}"/> </StackPanel> </DataTemplate> @@ -599,7 +674,7 @@ <StackPanel Orientation="Horizontal" Margin="2"> <TextBlock Margin="5 0 0 0" Text="{Binding Name}" FontWeight="SemiBold"/> <TextBlock Text=": "/> - <TextBlock Text="{Binding Value, StringFormat={}{0:0.0}}"/> + <TextBlock Text="{Binding Value, StringFormat={}{0:N0}}"/> <TextBlock Text="{Binding Unit}"/> </StackPanel> </DataTemplate> @@ -659,7 +734,8 @@ </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> - <StackPanel Orientation="Horizontal" Margin="4"> + <Border Background="Transparent" ToolTip="{Binding Quantity, Converter={StaticResource TooltipLiquidQuantityFormatConverter}, ConverterParameter='#,#\\'}"> + <StackPanel Orientation="Horizontal" Margin="4"> <Ellipse Width="30" Height="30"> <Ellipse.Fill> <SolidColorBrush Color="{Binding LiquidType,Converter={StaticResource LiquidTypeToColorConverter}}" /> @@ -668,17 +744,19 @@ <StackPanel Orientation="Vertical" Margin="4"> <TextBlock Text="{Binding LiquidType,Converter={StaticResource EnumToDescriptionConverter}}" FontWeight="SemiBold"></TextBlock> <TextBlock > - <Run Text="{Binding Quantity, Converter={StaticResource NanoLiterToLiterFormatConverter}}"></Run> + <Run Text="{Binding Quantity, Converter={StaticResource NanoLiterToLiterFormatConverter}, ConverterParameter='0.00'}"></Run> <Run Text=" liters"></Run> </TextBlock> </StackPanel> </StackPanel> + </Border> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> + <Border Background="Transparent" ToolTip="{Binding StatisticsValueCollection.TotalLiquidQuantities, Converter={StaticResource TooltipLiquidQuantityFormatConverter}, ConverterParameter='#,#\\'}"> <TextBlock DockPanel.Dock="Bottom" Margin="4 10 0 0 "> <Run Text="Total liquid quantities for all: " FontWeight="SemiBold"/> - <Run Text="{Binding StatisticsValueCollection.TotalLiquidQuantities, Converter={StaticResource NanoLiterToLiterFormatConverter}}"></Run> + <Run Text="{Binding StatisticsValueCollection.TotalLiquidQuantities, Converter={StaticResource NanoLiterToLiterFormatConverter}, ConverterParameter='0.00'}"></Run> <Run Text=" liters"></Run> <TextBlock.Style> <Style TargetType="TextBlock"> @@ -691,9 +769,19 @@ </Style> </TextBlock.Style> </TextBlock> + </Border> </DockPanel> </Border> </Grid> </Border> + <Grid Grid.Row="0" Grid.Column="1" Margin="20 0 20 0"> + <Border Padding="14 14 12 14" BorderBrush="DimGray" BorderThickness="0" Background="{StaticResource Logging.Background}" HorizontalAlignment="Stretch" CornerRadius="2" > + <Border.Effect> + <DropShadowEffect ShadowDepth="4" BlurRadius="10" Opacity="0.5"/> + </Border.Effect> + + <Button Grid.Column="1" HorizontalAlignment="Right" Command="{Binding ExportToExcelCommand}" Margin="0 0 10 0" Padding="10 15" Height="Auto" VerticalAlignment="Center" Width="Auto">EXPORT TO EXCEL</Button> + </Border> + </Grid> </Grid> </UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs index 2b3ed79ca..961d7f691 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs @@ -1,7 +1,9 @@ using LiveCharts; using LiveCharts.Wpf; using System; +using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -14,6 +16,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.SharedUI.Components; namespace Tango.MachineStudio.Statistics.Views { @@ -28,6 +31,8 @@ namespace Tango.MachineStudio.Statistics.Views InitializeComponent(); _lastSelectedGridItemIndex = -1; } + + private void Button_Click(object sender, RoutedEventArgs e) { selectMachineButton.IsChecked = true; @@ -68,6 +73,12 @@ namespace Tango.MachineStudio.Statistics.Views e.Handled = true; } + private void IsHeadCleaningButton_Click(object sender, RoutedEventArgs e) + { + isHeadCleaningToggleButton.IsChecked = true; + e.Handled = true; + } + private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { DataGrid dataGrid = sender as DataGrid; @@ -81,6 +92,84 @@ namespace Tango.MachineStudio.Statistics.Views } } } + + private void StartDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) + { + DatePicker datePickerObj = sender as DatePicker; + if(datePickerObj != null && datePickerObj.SelectedDate != null && endDatePicker.SelectedDate != null) + { + if(datePickerObj.SelectedDate> endDatePicker.SelectedDate) + { + BindingExpression start_be = datePickerObj.GetBindingExpression(DatePicker.SelectedDateProperty); + ValidationError validationError = new ValidationError(StartDateExpiredRule, start_be); + validationError.ErrorContent = "The start time must be less than or equal to end time."; + Validation.MarkInvalid(start_be, validationError); + } + else if (Validation.GetHasError(endDatePicker)) + { + BindingExpression end_be = endDatePicker.GetBindingExpression(DatePicker.SelectedDateProperty); + Validation.ClearInvalid(end_be); + } + } + } + + private void EndDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) + { + DatePicker datePickerObj = sender as DatePicker; + if (datePickerObj.SelectedDate != null && startdatePicker.SelectedDate != null ) + { + if(datePickerObj != null && datePickerObj.SelectedDate < startdatePicker.SelectedDate) + { + BindingExpression end_be = datePickerObj.GetBindingExpression(DatePicker.SelectedDateProperty); + ValidationError validationError = new ValidationError(EndDateExpiredRule, end_be); + validationError.ErrorContent = "The end time must be greater than or equal to the start time."; + Validation.MarkInvalid(end_be, validationError); + } + else if (Validation.GetHasError(startdatePicker)) + { + BindingExpression start_be = startdatePicker.GetBindingExpression(DatePicker.SelectedDateProperty); + Validation.ClearInvalid(start_be); + } + } + } + + private void CheckBox_PreventUndoCheck(object sender, RoutedEventArgs e) + { + if( sender is CheckBox) + { + CheckBox cb = sender as CheckBox; + if (cb.IsChecked == false) + { + cb.IsChecked = true; + e.Handled = true; + return; + } + } + e.Handled = false; + } + private void CheckBox_StayChecked(object sender, RoutedEventArgs e) + { + if (sender is CheckBox) + { + CheckBox cb = sender as CheckBox; + if (cb.IsChecked == false) + { + var col = cb.Tag; + Type type = col.GetType(); + if (col != null && col.GetType().GetGenericTypeDefinition() == typeof(SelectedObjectCollection<>)) + { + dynamic dSynchedSource = type.GetProperty("SynchedSource").GetValue(col); + if(dSynchedSource != null && dSynchedSource.GetType().GetGenericTypeDefinition() == typeof(ObservableCollection<>) && dSynchedSource.Count == 0) + { + cb.IsChecked = true; + e.Handled = true; + return; + } + } + } + } + e.Handled = false; + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs index 4205e5246..8f5c67f96 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs @@ -41,6 +41,7 @@ using RealTimeGraphX.WPF; using Tango.Core.ExtensionMethods; using System.Diagnostics; using Tango.BL.Builders; +using Tango.Core; namespace Tango.MachineStudio.Technician.ViewModels { @@ -83,6 +84,9 @@ namespace Tango.MachineStudio.Technician.ViewModels private DateTime _diagnosticsStartTime; private DateTime _diagnosticsNowTime; + private ProducerConsumerQueue<StartDiagnosticsResponse> _framesQueue; + private Thread _populateFramesThread; + #region Properties private ObservableCollection<MachineTechTabVM> _tabs; @@ -314,6 +318,8 @@ namespace Tango.MachineStudio.Technician.ViewModels /// <param name="notificationProvider">The notification provider.</param> public MachineTechViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IEventLogger eventLogger) { + _framesQueue = new ProducerConsumerQueue<StartDiagnosticsResponse>(); + Tabs = new ObservableCollection<MachineTechTabVM>(); Tabs.Add(new MachineTechTabVM() { IsSelected = true, Name = "Untitled" }); SelectedTab = Tabs.First(); @@ -448,13 +454,22 @@ namespace Tango.MachineStudio.Technician.ViewModels /// <param name="response">The response.</param> private void DiagnosticsFrameProvider_FrameReceived(object sender, StartDiagnosticsResponse response) { - PopulateDiagnosticsData(response); + _framesQueue.BlockEnqueue(response); } #endregion #region Populate Diagnostics Data + private void PopulateFramesThreadMethod() + { + while (!ApplicationManager.IsShuttingDown) + { + var frame = _framesQueue.BlockDequeue(); + PopulateDiagnosticsData(frame); + } + } + /// <summary> /// Populates the diagnostics data to the proper elements. /// </summary> @@ -2308,7 +2323,12 @@ namespace Tango.MachineStudio.Technician.ViewModels public override void OnApplicationReady() { - + if (_populateFramesThread == null) + { + _populateFramesThread = new Thread(PopulateFramesThreadMethod); + _populateFramesThread.IsBackground = true; + _populateFramesThread.Start(); + } } #endregion diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Converters/RoleEnumToVisibleConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Converters/RoleEnumToVisibleConverter.cs new file mode 100644 index 000000000..350257fdd --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Converters/RoleEnumToVisibleConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; +using Tango.BL.Enumerations; + +namespace Tango.MachineStudio.UsersAndRoles.Converters +{ + public class RoleEnumToVisibleConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if(value.GetType().IsEnum && Enum.IsDefined(typeof(Roles), value)) + { + Roles roleEnum = (Roles)value; + if (roleEnum.ToString().StartsWith("FSE")) + return Visibility.Collapsed; + } + + return Visibility.Visible; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj index 035cb2b9d..687544c1b 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj @@ -75,6 +75,7 @@ <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs"> <Link>GlobalVersionInfo.cs</Link> </Compile> + <Compile Include="Converters\RoleEnumToVisibleConverter.cs" /> <Compile Include="Navigation\UsersAndRolesNavigationManager.cs" /> <Compile Include="Navigation\UsersAndRolesNavigationView.cs" /> <Compile Include="Providers\PlaceAddress.cs" /> @@ -226,10 +227,11 @@ <ItemGroup> <Resource Include="Images\login.png" /> </ItemGroup> + <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml index 3964abfc8..2a8621e5c 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml @@ -14,6 +14,7 @@ xmlns:entities="clr-namespace:Tango.BL.Entities;assembly=Tango.BL" xmlns:local="clr-namespace:Tango.MachineStudio.UsersAndRoles.Views" xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:localconverters="clr-namespace:Tango.MachineStudio.UsersAndRoles.Converters" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> @@ -21,6 +22,7 @@ <providers:PlacesProvider x:Key="PlacesProvider" /> <converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"></converters:BooleanToVisibilityConverter> <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter"></converters:BooleanToVisibilityInverseConverter> + <localconverters:RoleEnumToVisibleConverter x:Key="RoleEnumToVisibleConverter"/> </UserControl.Resources> <Grid> @@ -103,7 +105,7 @@ </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate DataType="{x:Type entities:Role}"> - <Grid> + <Grid Visibility="{Binding RoleEnum, Converter={StaticResource RoleEnumToVisibleConverter}}"> <Grid.ToolTip> <StackPanel Background="Transparent"> <TextBlock Text="{Binding Description}" FontSize="10" Margin="0 0 0 10"></TextBlock> @@ -175,7 +177,7 @@ <ListBox ItemsSource="{Binding Roles}" ItemContainerStyle="{StaticResource basicListBoxItem}" HorizontalContentAlignment="Stretch" Background="Transparent"> <ListBox.ItemTemplate> <DataTemplate> - <Grid Background="Transparent" IsHitTestVisible="True" Style="{StaticResource draggableGrid}" dragAndDrop:DragAndDropService.DraggableBorderBrush="{StaticResource AccentColorBrush}" dragAndDrop:DragAndDropService.Draggable="True" dragAndDrop:DragAndDropService.DraggingSurface="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DraggingSurface}"> + <Grid Background="Transparent" IsHitTestVisible="True" Style="{StaticResource draggableGrid}" dragAndDrop:DragAndDropService.DraggableBorderBrush="{StaticResource AccentColorBrush}" dragAndDrop:DragAndDropService.Draggable="True" dragAndDrop:DragAndDropService.DraggingSurface="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DraggingSurface}" Visibility="{Binding RoleEnum, Converter={StaticResource RoleEnumToVisibleConverter}}"> <Grid.ToolTip> <StackPanel Background="Transparent"> <TextBlock Text="{Binding Description}" FontSize="10" Margin="0 0 0 10"></TextBlock> |
