From d33c19b3ac6803de4b5c8d475832efef131c1a45 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 30 Dec 2020 15:11:34 +0000 Subject: Revert "Hope it is fine" --- .../Views/DispenserView.xaml | 6 +- .../ActionLogsModule.cs | 62 ++ .../Tango.MachineStudio.ActionLogs/App.xaml | 12 + .../Images/action_logs.jpg | Bin 0 -> 25603 bytes .../Images/actionlogs_title.png | Bin 0 -> 12112 bytes .../Properties/AssemblyInfo.cs | 19 + .../Properties/Resources.Designer.cs | 71 ++ .../Properties/Resources.resx | 117 +++ .../Properties/Settings.Designer.cs | 30 + .../Properties/Settings.settings | 7 + .../Tango.MachineStudio.ActionLogs.csproj | 163 +++++ .../ViewModelLocator.cs | 29 + .../ViewModels/MainViewVM.cs | 290 ++++++++ .../Views/MainView.xaml | 317 +++++++++ .../Views/MainView.xaml.cs | 34 + .../Tango.MachineStudio.ActionLogs/app.config | 85 +++ .../Tango.MachineStudio.ActionLogs/packages.config | 9 + .../ViewModels/MainViewVM.cs | 53 +- .../Views/CatalogView.xaml | 4 +- .../ViewModels/MainViewVM.cs | 4 +- .../Controls/JobOutlineControl.cs | 28 + .../ViewModels/MainViewVM.cs | 342 +++++---- .../Views/InsufficientLiquidQuantityView.xaml | 67 +- .../Views/InsufficientLiquidQuantityView.xaml.cs | 6 +- .../Views/JobView.xaml | 227 +++--- .../Views/JobView.xaml.cs | 45 +- .../Views/MachineJobSelectionView.xaml | 8 +- .../Views/MainView.xaml | 58 +- .../Views/RunningJobView.xaml | 2 +- ...eStudio.HardwareDesigner_ijdp5tm3_wpftmp.csproj | 184 +++++ .../ViewModels/ComparisonWizardViewVM.cs | 8 +- .../ViewModels/MainViewVM.cs | 85 ++- .../Views/MainView.xaml | 7 +- .../ViewModels/ApplicationLogsViewVM.cs | 22 +- .../Views/ApplicationLogsView.xaml | 2 +- .../Views/EmbeddedLogDetailsView.xaml | 2 +- .../Views/TimelineView.xaml | 15 +- .../Tango.MachineStudio.MachineDesigner.csproj | 26 +- .../ViewModels/ColorCalibrationViewVM.cs | 10 + .../ViewModels/HardwareConfigurationViewVM.cs | 32 +- .../ViewModels/MachineCreationDialogVM.cs | 45 ++ .../ViewModels/MachineUpdateDetailsDialogVM.cs | 20 + .../ViewModels/MachineUpdatesViewVM.cs | 198 ++++++ .../ViewModels/MainViewVM.cs | 319 ++++++++- .../ViewModels/TupViewVM.cs | 129 ++++ .../Views/MachineCreationDialog.xaml | 47 +- .../Views/MachineDetailsView.xaml | 16 +- .../Views/MachineSettingsView.xaml | 184 +++-- .../Views/MachineUpdateDetailsDialog.xaml | 94 +++ .../Views/MachineUpdateDetailsDialog.xaml.cs | 28 + .../Views/MachineUpdatesView.xaml | 114 +++ .../Views/MachineUpdatesView.xaml.cs | 28 + .../Views/MachinesView.xaml | 4 +- .../Views/MainView.xaml | 2 +- .../Views/SpoolsView.xaml | 11 +- .../Views/TupView.xaml | 60 ++ .../Views/TupView.xaml.cs | 28 + .../Models/CalibrationMeasurementModel.cs | 90 +++ .../Models/ColorLinearizationModel.cs | 43 ++ .../Tango.MachineStudio.RML.csproj | 49 ++ .../ViewModels/CalibrationDataViewVM.cs | 10 + .../ViewModels/ColorCalibrationViewVM.cs | 551 +++++++++++++++ .../ViewModels/ColorConversionViewVM.cs | 16 +- .../ViewModels/LiquidVolumeVM.cs | 13 + .../ViewModels/MainViewVM.cs | 420 ++++++++--- .../ViewModels/RmlDeleteDialogViewVM.cs | 95 +++ .../Views/ColorCalibrationView.xaml | 213 ++++++ .../Views/ColorCalibrationView.xaml.cs | 42 ++ .../Views/HeadCleaningParametersView.xaml | 59 ++ .../Views/HeadCleaningParametersView.xaml.cs | 28 + .../Tango.MachineStudio.RML/Views/MainView.xaml | 2 +- .../Views/ProcessParametersView.xaml | 4 +- .../Views/RmlDeleteDialogView.xaml | 82 +++ .../Views/RmlDeleteDialogView.xaml.cs | 28 + .../Tango.MachineStudio.RML/Views/RmlView.xaml | 47 +- .../Tango.MachineStudio.RML/Views/RmlsView.xaml | 8 +- .../Tango.MachineStudio.RML/Views/SpoolsView.xaml | 85 +++ .../Views/SpoolsView.xaml.cs | 28 + .../Views/ThreadParametersView.xaml | 121 ++++ .../Views/ThreadParametersView.xaml.cs | 28 + .../Modules/Tango.MachineStudio.Sites/App.xaml | 12 + .../Contracts/IMainView.cs | 20 + .../Images/machine_site.png | Bin 0 -> 207547 bytes .../Tango.MachineStudio.Sites/Images/site.png | Bin 0 -> 22073 bytes .../Tango.MachineStudio.Sites/Models/SiteModel.cs | 18 + .../Properties/AssemblyInfo.cs | 19 + .../Properties/Resources.Designer.cs | 62 ++ .../Properties/Resources.resx | 117 +++ .../Properties/Settings.Designer.cs | 30 + .../Properties/Settings.settings | 7 + .../Tango.MachineStudio.Sites/SitesModule.cs | 62 ++ .../Tango.MachineStudio.Sites.csproj | 177 +++++ .../Tango.MachineStudio.Sites/ViewModelLocator.cs | 29 + .../ViewModels/MainViewVM.cs | 220 ++++++ .../ViewModels/SiteDetailsViewVM.cs | 175 +++++ .../Tango.MachineStudio.Sites/Views/MainView.xaml | 19 + .../Views/MainView.xaml.cs | 36 + .../Views/SiteDetailsView.xaml | 170 +++++ .../Views/SiteDetailsView.xaml.cs | 28 + .../Tango.MachineStudio.Sites/Views/SitesView.xaml | 76 ++ .../Views/SitesView.xaml.cs | 28 + .../Modules/Tango.MachineStudio.Sites/app.config | 85 +++ .../Tango.MachineStudio.Sites/packages.config | 9 + .../Tango.MachineStudio.Statistics/App.config | 20 +- .../Converters/CollectionConverter .cs | 48 ++ .../Converters/DateTimeToStringFormatConverter.cs | 30 + .../Converters/JobLengthConverter.cs | 41 ++ .../LiquidQuantityToFormatStringConverter.cs | 41 ++ .../Converters/LiquidTypeToColorConverter.cs | 43 ++ .../MidTankLevelToElementHeightConverter.cs | 41 ++ .../Converters/NanoLiterToLiterFormatConverter.cs | 36 + .../Converters/StringToBoolYesNoNullConverter.cs | 37 + .../Converters/StringToFirstLetterConverter.cs | 30 + .../TooltipLiquidQuantityFormatConverter.cs | 38 + .../Models/ExcelModel.cs | 34 + .../Models/JobRunModel.cs | 39 + .../Models/JobRunStatisticsModel.cs | 45 ++ .../Models/RmlModel.cs | 15 + .../Models/StatisticsValueCollection.cs | 319 +++++++++ .../Models/TotalLiquidQuantityModel.cs | 15 + .../Tango.MachineStudio.Statistics.csproj | 48 ++ .../Tooltips/PieChartTooltipControl.xaml | 2 +- .../ValidationRules/DateExpiredRule.cs | 21 + .../ViewModels/ChartsViewVM.cs | 364 ++++++++++ .../ViewModels/JobRunsViewVM.cs | 729 +++++++++++++++++++ .../ViewModels/MainViewVM.cs | 339 +-------- .../Views/ChartsView.xaml | 145 ++++ .../Views/ChartsView.xaml.cs | 74 ++ .../Views/JobRunsView.xaml | 787 +++++++++++++++++++++ .../Views/JobRunsView.xaml.cs | 175 +++++ .../Views/MainView.xaml | 114 +-- .../Views/MainView.xaml.cs | 6 +- .../Tango.MachineStudio.Statistics/packages.config | 1 + ...go.MachineStudio.Storage_yjpbed13_wpftmp.csproj | 154 ++++ .../Editors/BlowerElementEditor.xaml | 6 +- .../Editors/ControllerElementEditor.xaml | 6 +- .../Editors/DispenserElementEditor.xaml | 2 +- .../Editors/HeaterElementEditor.xaml | 4 +- .../Editors/JobRunnerElementEditor.xaml | 2 +- .../Editors/MotorElementEditor.xaml | 2 +- .../Editors/ProcessParametersElementEditor.xaml | 4 +- .../Editors/ThreadMotionElementEditor.xaml | 2 +- .../Editors/ValveElementEditor.xaml | 6 +- .../ViewModels/MachineTechViewVM.cs | 331 ++++++--- .../Converters/RoleEnumToVisibleConverter.cs | 32 + .../Images/login.png | Bin 0 -> 6401 bytes .../Tango.MachineStudio.UsersAndRoles.csproj | 19 +- .../ViewModels/MainViewVM.cs | 127 +++- .../ViewModels/UserCreationDialogVM.cs | 74 ++ .../Views/OrganizationManagementView.xaml | 26 + .../Views/UserCreationDialog.xaml | 53 ++ .../Views/UserCreationDialog.xaml.cs | 28 + .../Views/UserManagementView.xaml | 18 +- .../Views/UserView.xaml | 2 - .../packages.config | 1 + .../Authentication/IAuthenticationProvider.cs | 2 +- .../EventLogging/DefaultEventLogger.cs | 65 +- .../EventLogging/IEventLogger.cs | 5 + .../Fonts/Flexo-Black.otf | Bin 0 -> 112924 bytes .../Fonts/Flexo-BlackIt.otf | Bin 0 -> 121948 bytes .../Fonts/Flexo-Bold.otf | Bin 0 -> 112436 bytes .../Fonts/Flexo-BoldIt.otf | Bin 0 -> 121352 bytes .../Fonts/Flexo-Demi.otf | Bin 0 -> 112936 bytes .../Fonts/Flexo-DemiIt.otf | Bin 0 -> 122096 bytes .../Fonts/Flexo-Heavy.otf | Bin 0 -> 112632 bytes .../Fonts/Flexo-HeavyIt.otf | Bin 0 -> 122220 bytes .../Tango.MachineStudio.Common/Fonts/Flexo-It.otf | Bin 0 -> 120816 bytes .../Fonts/Flexo-Light.otf | Bin 0 -> 112116 bytes .../Fonts/Flexo-LightIt.otf | Bin 0 -> 120472 bytes .../Fonts/Flexo-Medium.otf | Bin 0 -> 112016 bytes .../Fonts/Flexo-MediumIt.otf | Bin 0 -> 121092 bytes .../Fonts/Flexo-Regular.otf | Bin 0 -> 111924 bytes .../Fonts/Flexo-Thin.otf | Bin 0 -> 112040 bytes .../Fonts/Flexo-ThinIt.otf | Bin 0 -> 120108 bytes .../Images/machine_new.png | Bin 0 -> 43275 bytes .../Images/machine_new_small.png | Bin 0 -> 16963 bytes .../MachineStudioSettings.cs | 37 +- .../Publish/MachineStudioPublisher.cs | 50 ++ .../Publish/PublishOptions.cs | 21 + .../Resources/MaterialDesign.xaml | 152 +++- .../StudioApplication/IStudioApplicationManager.cs | 5 + .../Tango.MachineStudio.Common.csproj | 45 ++ .../Themes/DarkThemeColors.xaml | 5 + .../Themes/LightThemeColors.xaml | 123 ++-- .../Tup/TupFileBuilder.cs | 288 ++++++++ .../Tup/TupFileBuilderProgressEventArgs.cs | 16 + .../Web/CheckForUpdatesResponse.cs | 2 + .../Web/DownloadLatestPPCVersionRequest.cs | 14 + .../Web/DownloadLatestPPCVersionResponse.cs | 21 + .../Web/DownloadLatestVersionResponse.cs | 2 + .../Tango.MachineStudio.Common/Web/LoginMethod.cs | 17 + .../Tango.MachineStudio.Common/Web/LoginRequest.cs | 1 + .../Web/LoginResponse.cs | 1 + .../Web/MachineStudioWebClientBase.cs | 18 + .../Tango.MachineStudio.Common/packages.config | 1 + .../MainWindow.xaml | 8 +- .../Tango.MachineStudio.Publisher.UI.csproj | 6 +- .../Tango.MachineStudio.UI/App.config | 4 + .../Tango.MachineStudio.UI/App.xaml.cs | 72 +- .../DefaultAuthenticationProvider.cs | 26 +- .../Console/ConsoleWindow.xaml | 4 +- .../Images/active_directory.png | Bin 0 -> 15300 bytes .../Images/external-bridge-emulator.png | Bin 3554 -> 6412 bytes .../Images/external-bridge-signalr.png | Bin 0 -> 5399 bytes .../Images/external-bridge-tcp.png | Bin 3618 -> 5653 bytes .../Images/external-bridge-usb.png | Bin 3623 -> 5669 bytes .../Tango.MachineStudio.UI/Images/login.png | Bin 0 -> 6401 bytes .../Tango.MachineStudio.UI/Images/login_white.png | Bin 0 -> 3308 bytes .../Images/machinestudio_login.png | Bin 0 -> 21788 bytes .../Tango.MachineStudio.UI/MainWindow.xaml | 2 +- .../Tango.MachineStudio.UI/MainWindow.xaml.cs | 2 + .../Notifications/DialogWindow.xaml | 2 +- .../Notifications/MessageBoxWindow.xaml | 4 +- .../Notifications/TextInputBoxWindow.xaml | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../DefaultStudioApplicationManager.cs | 35 +- .../TFS/TeamFoundationServiceExtendedClient.cs | 75 +- .../TFS/TeamMembersProvider.cs | 3 +- .../Tango.MachineStudio.UI.csproj | 77 +- .../Tango.MachineStudio.UI/ViewModelLocator.cs | 19 +- .../ViewModels/ConnectedMachineViewVM.cs | 6 +- .../ViewModels/ConnectionLostViewVM.cs | 64 ++ .../ViewModels/FirmwareUpgradeViewVM.cs | 6 + .../ViewModels/LoginViewVM.cs | 170 ++++- .../ViewModels/MachineConnectionViewVM.cs | 14 + .../ViewModels/MachineLoginViewVM.cs | 7 +- .../ViewModels/MainViewVM.cs | 251 ++++--- .../ViewModels/UpdateViewVM.cs | 3 +- .../Tango.MachineStudio.UI/Views/AboutView.xaml | 6 +- .../Views/ConnectedMachineView.xaml | 58 ++ .../Views/ConnectionLostView.xaml | 11 +- .../Views/FirmwareUpgradeView.xaml | 2 +- .../Tango.MachineStudio.UI/Views/LoadingView.xaml | 2 +- .../Tango.MachineStudio.UI/Views/LoginView.xaml | 120 +++- .../Views/MachineConnectionView.xaml | 28 +- .../Views/MachineLoginView.xaml | 25 +- .../Views/MachineSerialView.xaml | 2 +- .../Tango.MachineStudio.UI/Views/MainView.xaml | 158 +++-- .../Views/ReportIssueView.xaml | 2 +- .../Tango.MachineStudio.UI/Views/ShutdownView.xaml | 2 +- .../Windows/ExceptionWindow.xaml | 2 +- .../Windows/ModuleWindow.xaml | 14 +- .../Windows/ModuleWindow.xaml.cs | 9 + .../Tango.MachineStudio.UI/machine_new_small.ico | Bin 0 -> 132825 bytes 244 files changed, 12481 insertions(+), 1567 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ActionLogsModule.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/App.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/action_logs.jpg create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/actionlogs_title.png create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.Designer.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.resx create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.Designer.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.settings create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Tango.MachineStudio.ActionLogs.csproj create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModelLocator.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModels/MainViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/app.config create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/packages.config create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Tango.MachineStudio.HardwareDesigner_ijdp5tm3_wpftmp.csproj create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdateDetailsDialogVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Models/CalibrationMeasurementModel.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Models/ColorLinearizationModel.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/ColorCalibrationViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/RmlDeleteDialogViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ColorCalibrationView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ColorCalibrationView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/HeadCleaningParametersView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/HeadCleaningParametersView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlDeleteDialogView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlDeleteDialogView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/SpoolsView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/SpoolsView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ThreadParametersView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ThreadParametersView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/App.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Contracts/IMainView.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/machine_site.png create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/site.png create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Models/SiteModel.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/AssemblyInfo.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Resources.Designer.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Resources.resx create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Settings.Designer.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Properties/Settings.settings create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/SitesModule.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Tango.MachineStudio.Sites.csproj create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModelLocator.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/DateTimeToStringFormatConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/JobLengthConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidQuantityToFormatStringConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidTypeToColorConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/MidTankLevelToElementHeightConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/NanoLiterToLiterFormatConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToBoolYesNoNullConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToFirstLetterConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/TooltipLiquidQuantityFormatConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/ExcelModel.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunStatisticsModel.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/RmlModel.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/StatisticsValueCollection.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/TotalLiquidQuantityModel.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ValidationRules/DateExpiredRule.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage_yjpbed13_wpftmp.csproj create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Converters/RoleEnumToVisibleConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Images/login.png create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/ViewModels/UserCreationDialogVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Black.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-BlackIt.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Bold.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-BoldIt.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Demi.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-DemiIt.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Heavy.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-HeavyIt.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-It.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Light.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-LightIt.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Medium.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-MediumIt.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Regular.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Thin.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-ThinIt.otf create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Images/machine_new.png create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Images/machine_new_small.png create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/LoginMethod.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/active_directory.png create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/external-bridge-signalr.png create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/login.png create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/login_white.png create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Images/machinestudio_login.png create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/machine_new_small.ico (limited to 'Software/Visual_Studio/MachineStudio') 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 977ab865a..e0f93df5a 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/MachineStudio.Dispensers/Views/DispenserView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/MachineStudio.Dispensers/Views/DispenserView.xaml @@ -19,7 +19,7 @@ DISPENSER @@ -51,9 +51,9 @@ Dispenser Type: - + - Nanoliter / Pulse: + Nanoliter / Pulse: Part Number: diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ActionLogsModule.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ActionLogsModule.cs new file mode 100644 index 000000000..3a9dcdfaa --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ActionLogsModule.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; +using Tango.BL.Enumerations; +using Tango.MachineStudio.Common; +using Tango.MachineStudio.ActionLogs.Views; +using Tango.SharedUI.Helpers; + +namespace Tango.MachineStudio.ActionLogs +{ + [StudioModule(21)] + public class ActionLogsModule : StudioModuleBase + { + public override string Name + { + get + { + return "Action Logs"; + } + } + + public override string Description + { + get + { + return "Monitor and track changes made to Twine's global datasets."; + } + } + + public override BitmapSource Image + { + get + { + return ResourceHelper.GetImageFromResources("Images/action_logs.jpg"); + } + } + + public override Type MainViewType + { + get + { + return typeof(MainView); + } + } + + public override Permissions Permission + { + get + { + return Permissions.RunMachineStudio; + } + } + + public override void Dispose() + { + + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/App.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/App.xaml new file mode 100644 index 000000000..3ab646c7c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/App.xaml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/action_logs.jpg b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/action_logs.jpg new file mode 100644 index 000000000..75f39c09c Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/action_logs.jpg differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/actionlogs_title.png b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/actionlogs_title.png new file mode 100644 index 000000000..299c14c6d Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Images/actionlogs_title.png differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/AssemblyInfo.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..072265a74 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +[assembly: AssemblyTitle("Tango - Machine Studio Action Logs Module")] +[assembly: AssemblyVersion("1.0.0.1737")] + +[assembly: ComVisible(false)] + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.Designer.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.Designer.cs new file mode 100644 index 000000000..796a67686 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Tango.MachineStudio.ActionLogs.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tango.MachineStudio.ActionLogs.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.resx b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.resx new file mode 100644 index 000000000..af7dbebba --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.Designer.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.Designer.cs new file mode 100644 index 000000000..507ac539d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Tango.MachineStudio.ActionLogs.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.settings b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.settings new file mode 100644 index 000000000..033d7a5e9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Tango.MachineStudio.ActionLogs.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Tango.MachineStudio.ActionLogs.csproj new file mode 100644 index 000000000..de4783237 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Tango.MachineStudio.ActionLogs.csproj @@ -0,0 +1,163 @@ + + + + + Debug + AnyCPU + {447ECB9F-F730-47D6-8DF8-D232BF4A0315} + library + Tango.MachineStudio.ActionLogs + Tango.MachineStudio.ActionLogs + v4.6.1 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + + + true + full + false + ..\..\..\Build\Machine Studio\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\..\..\Build\Machine Studio\Release\ + TRACE + prompt + 4 + + + + ..\..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + + ..\..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll + + + ..\..\..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll + + + ..\..\..\packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll + + + ..\..\..\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll + + + ..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + ..\..\..\packages\MahApps.Metro.1.5.0\lib\net45\System.Windows.Interactivity.dll + + + + + + + + + 4.0 + + + + + + + + GlobalVersionInfo.cs + + + + + MainView.xaml + + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + {f441feee-322a-4943-b566-110e12fd3b72} + Tango.BL + + + {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} + Tango.Core + + + {4206ac58-3b57-4699-8835-90bf6db01a61} + Tango.Integration + + + {bc932dbd-7cdb-488c-99e4-f02cf441f55e} + Tango.Logging + + + {d8f1ad85-526a-4f50-b6dc-d437af63d8d8} + Tango.Settings + + + {8491D07B-C1F6-4B62-A412-41B9FD2D6538} + Tango.SharedUI + + + {74e700b0-1156-4126-be40-ee450d3c3026} + Tango.Transport + + + {cb0b0aa2-bb24-4bca-a720-45e397684e12} + Tango.MachineStudio.Common + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModelLocator.cs new file mode 100644 index 000000000..29540fa86 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModelLocator.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.MachineStudio.ActionLogs.ViewModels; + +namespace Tango.MachineStudio.ActionLogs +{ + public static class ViewModelLocator + { + /// + /// Initializes a new instance of the ViewModelLocator class. + /// + static ViewModelLocator() + { + TangoIOC.Default.Register(); + } + + public static MainViewVM MainViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModels/MainViewVM.cs new file mode 100644 index 000000000..3e5c59fee --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/ViewModels/MainViewVM.cs @@ -0,0 +1,290 @@ + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data.Entity; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Tango.BL; +using Tango.BL.Builders; +using Tango.BL.Entities; +using Tango.BL.Enumerations; +using Tango.BL.ValueObjects; +using Tango.Core.Commands; +using Tango.Core.ExtensionMethods; +using Tango.MachineStudio.Common; +using Tango.MachineStudio.Common.Notifications; +using Tango.SharedUI.Components; + +namespace Tango.MachineStudio.ActionLogs.ViewModels +{ + public class MainViewVM : StudioViewModel + { + private INotificationProvider _notification; + private List _allUsers; + + #region Properties + + private DateTime _startSelectedDate; + public DateTime StartSelectedDate + { + get { return _startSelectedDate; } + set { _startSelectedDate = value; RaisePropertyChangedAuto(); } + } + + private DateTime _endSelectedDate; + public DateTime EndSelectedDate + { + get { return _endSelectedDate; } + set { _endSelectedDate = value; RaisePropertyChangedAuto(); } + } + + private string _searchFilter; + public string SearchFilter + { + get { return _searchFilter; } + set { _searchFilter = value; RaisePropertyChangedAuto(); } + } + + private ObservableCollection _actionLogs; + public ObservableCollection ActionLogs + { + get { return _actionLogs; } + set { _actionLogs = value; RaisePropertyChanged(nameof(ActionLogs)); } + } + + private SelectedObjectCollection _selectedActionLogTypes; + public SelectedObjectCollection SelectedActionLogTypes + { + get { return _selectedActionLogTypes; } + set + { + _selectedActionLogTypes = value; + RaisePropertyChanged(nameof(SelectedActionLogTypes)); + } + } + + private ActionLog _selectedActionLog = null; + public ActionLog SelectedActionLog + { + get { return _selectedActionLog; } + set + { + _selectedActionLog = value; + SelectedItemChanged(); + RaisePropertyChangedAuto(); + InvalidateRelayCommands(); + } + } + + private ActionLogDifference _differenceObject; + public ActionLogDifference DifferenceObject + { + get { return _differenceObject; } + set { _differenceObject = value; RaisePropertyChangedAuto(); } + } + + private bool _isLoading; + + public bool IsLoading + { + get { return _isLoading; } + set { _isLoading = value; RaisePropertyChangedAuto(); } + } + + private bool _isLoadingDifferences; + + public bool IsLoadingDifferences + { + get { return _isLoadingDifferences; } + set { _isLoadingDifferences = value; RaisePropertyChangedAuto(); } + } + + + + + #endregion + + public RelayCommand SearchCommand { get; set; } + public RelayCommand CopyToClipBoardCommand { get; set; } + public RelayCommand CopyRelateObjectIDCommand { get; set; } + + public MainViewVM(INotificationProvider notification) + { + _notification = notification; + + IsLoading = false; + IsLoadingDifferences = false; + ActionLogs = new ObservableCollection(); + SearchCommand = new RelayCommand(async () => await GetActionLogs(), () => IsFree); + CopyRelateObjectIDCommand = new RelayCommand(CopyRelateObjectID); + CopyToClipBoardCommand = new RelayCommand(CopyToClipBoard, () => SelectedActionLog != null && SelectedActionLog.DifferenceObject != null); + DateTime now = DateTime.Now; + StartSelectedDate = now.AddMonths(-1); + EndSelectedDate = now; + var source = Enum.GetValues(typeof(ActionLogType)).Cast().ToObservableCollection(); + var syncedSource = Enum.GetValues(typeof(ActionLogType)).Cast().ToObservableCollection(); + + SelectedActionLogTypes = new SelectedObjectCollection(source, syncedSource); + } + + public override void OnApplicationReady() + { + InitUsers(); + } + public async void InitUsers() + { + try + { + IsFree = false; + + using (var db = ObservablesContext.CreateDefault()) + { + + _allUsers = await db.Users.Include(x => x.Contact).ToListAsync(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading users."); + } + finally + { + IsFree = true; + } + } + + private void CopyToClipBoard() + { + DataObject data = new DataObject(SelectedActionLog.DifferenceObject.ToJsonString()); + System.Windows.Clipboard.SetDataObject(data); + + } + private void CopyRelateObjectID() + { + DataObject data = new DataObject(SelectedActionLog.RelatedObjectGuid); + System.Windows.Clipboard.SetDataObject(data); + } + + /// + /// New Database Query with search parameters. Initialization ActionLogs property. + /// + private async Task GetActionLogs() + { + IsLoading = true; + string filter = SearchFilter?.ToLower(); + + if (String.IsNullOrWhiteSpace(filter)) filter = null; + + try + { + IsFree = false; + + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + DateTime startUtc = new DateTime(StartSelectedDate.Year, StartSelectedDate.Month, StartSelectedDate.Day, 0, 0, 0).ToUniversalTime(); + TimeSpan offsetTime = (EndSelectedDate.Date == DateTime.Now.Date) ? DateTime.Now.TimeOfDay : new TimeSpan(23, 59, 59); + DateTime endUtc = EndSelectedDate.ToUniversalTime() + offsetTime; + + Debug.Write($"TEST TIME {startUtc} to {endUtc} "+ System.Environment.NewLine); + + var db_ActionLogs = db.ActionLogs.Where(x => x.LastUpdated <= endUtc && x.LastUpdated >= startUtc) + .Select(x => new + { + x.ID, + x.Guid, + x.UserGuid, + x.LastUpdated, + x.Type, + x.RelatedObjectName, + x.RelatedObjectGuid, + x.Message + }); + + int[] actionTypes = SelectedActionLogTypes.SynchedSource.ToArray().Select(x => (int)x).ToArray(); + if (actionTypes.Length > 0) + { + db_ActionLogs = db_ActionLogs.Where(x => actionTypes.Contains(x.Type)); + } + + var runs_db = await db_ActionLogs.ToListAsync(); + var runs = runs_db.Select(x => new ActionLog() + { + ID = x.ID, + Guid = x.Guid, + UserGuid = x.UserGuid, + LastUpdated = x.LastUpdated, + Type = x.Type, + RelatedObjectName = x.RelatedObjectName, + RelatedObjectGuid = x.RelatedObjectGuid, + Message = x.Message, + User = _allUsers.SingleOrDefault(y => y.Guid == x.UserGuid) + }); + + if (!String.IsNullOrEmpty(filter)) + { + runs = runs.Where(x => x.ID.ToString().ToLower().StartsWith(filter) || (x.RelatedObjectName != null && x.RelatedObjectName.ToLower().StartsWith(filter)) + || (x.RelatedObjectGuid != null && x.RelatedObjectGuid.ToLower().StartsWith(filter)) + || (x.User != null && x.User.Contact != null && x.User.Contact.FullName.ToLower().StartsWith(filter))); + } + ActionLogs = runs.ToObservableCollection(); + } + } + catch (Exception ex) + { + IsFree = true; + LogManager.Log(ex, "Error getting action logs."); + _notification.ShowError($"Error occurred while trying to retrieve the action logs.\n{ex.Message}"); + } + finally + { + IsFree = true; + IsLoading = false; + } + } + + /// + /// Update DifferenceObject on Selected item changed + /// + private async void SelectedItemChanged() + { + if (SelectedActionLog == null) + return; + if (SelectedActionLog.Difference == null) + { + await InitSelectedActionLogDifference(); + } + DifferenceObject = SelectedActionLog.DifferenceObject; + } + + /// + /// Initializes the selected action log difference. + /// + public async Task InitSelectedActionLogDifference() + { + IsLoadingDifferences = true; + try + { + using (var db = ObservablesContext.CreateDefault()) + { + var difference = await db.ActionLogs.SingleOrDefaultAsync(x => x.Guid.Equals(SelectedActionLog.Guid)); + if (difference != null) + { + SelectedActionLog.DifferenceObject = difference.DifferenceObject; + } + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading difference of the selected action log."); + } + finally + { + IsLoadingDifferences = false; + } + } + } +} 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 new file mode 100644 index 000000000..146735eaa --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + Action Logs + Select start/end dates and action log types to trace system changes. + + + + + + + + + + + + + + + + + + + + + + Start Date: + + + + End Date: + + + + + + + + + + + + + + () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Object Changes + + + + + + + + + + + + + + + + + + + + : + + | + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml.cs new file mode 100644 index 000000000..67641e3fc --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml.cs @@ -0,0 +1,34 @@ +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.ActionLogs.Views +{ + /// + /// Interaction logic for MainView.xaml + /// + public partial class MainView : UserControl + { + public MainView() + { + InitializeComponent(); + } + + private void Button_Click(object sender, RoutedEventArgs e) + { + selectActionsButton.IsChecked = true; + e.Handled = true; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/app.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/app.config new file mode 100644 index 000000000..7b82e5f7c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/app.config @@ -0,0 +1,85 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/packages.config new file mode 100644 index 000000000..e57143046 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs index 652ad3093..8a33f15ef 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs @@ -17,6 +17,10 @@ using Microsoft.Win32; using Tango.Core.Helpers; using System.IO; using Tango.MachineStudio.Catalogs.Excel; +using Tango.BL.ActionLogs; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.Enumerations; +using Tango.BL.DTO; namespace Tango.MachineStudio.Catalogs.ViewModels { @@ -25,6 +29,9 @@ namespace Tango.MachineStudio.Catalogs.ViewModels private ObservablesContext _catalogsContext; private ObservablesContext _activeCatalogContext; private INotificationProvider _notification; + private IActionLogManager _actionLogManager; + private IAuthenticationProvider _authentication; + private ColorCatalogDTO _catalogBeforeSave; #region Properties @@ -151,9 +158,11 @@ namespace Tango.MachineStudio.Catalogs.ViewModels /// Initializes a new instance of the class. /// /// The notification provider. - public MainViewVM(INotificationProvider notificationProvider) : this() + public MainViewVM(INotificationProvider notificationProvider, IActionLogManager actionLogManager, IAuthenticationProvider authenticationProvider) : this() { + _actionLogManager = actionLogManager; _notification = notificationProvider; + _authentication = authenticationProvider; } #endregion @@ -197,7 +206,7 @@ namespace Tango.MachineStudio.Catalogs.ViewModels _activeCatalogContext = ObservablesContext.CreateDefault(); - ActiveCatalog = await new ColorCatalogBuilder(_activeCatalogContext).Set(SelectedCatalog.Guid).WithGroups().WithItems().WithRecipes().BuildAsync(); + ActiveCatalog = await new CatalogBuilder(_activeCatalogContext).Set(SelectedCatalog.Guid).WithGroups().WithItems().WithRecipes().BuildAsync(); SelectedGroup = ActiveCatalog.ColorCatalogsGroups.FirstOrDefault(); RMLS = await _activeCatalogContext.Rmls.ToListAsync(); @@ -206,6 +215,8 @@ namespace Tango.MachineStudio.Catalogs.ViewModels SelectedItem = SelectedGroup.ColorCatalogsItems.FirstOrDefault(); } + _catalogBeforeSave = ColorCatalogDTO.FromObservable(ActiveCatalog); + View.NavigateTo(CatalogsNavigationView.CatalogView); } catch (Exception ex) @@ -233,6 +244,7 @@ namespace Tango.MachineStudio.Catalogs.ViewModels { IsFree = false; await SelectedCatalog.DeleteCascadeAsync(_catalogsContext); + _actionLogManager.InsertLog(ActionLogType.CatalogDeleted, _authentication.CurrentUser, SelectedCatalog.Name, SelectedCatalog, "Catalog deleted using Machine Studio.", false); SelectedCatalog = null; } catch (Exception ex) @@ -265,6 +277,7 @@ namespace Tango.MachineStudio.Catalogs.ViewModels newCatalog.Company = "Twine"; _catalogsContext.ColorCatalogs.Add(newCatalog); await _catalogsContext.SaveChangesAsync(); + _actionLogManager.InsertLog(ActionLogType.CatalogCreated, _authentication.CurrentUser, newCatalog.Name, newCatalog, "Catalog created using Machine Studio."); SelectedCatalog = newCatalog; EditSelectedCatalog(); } @@ -305,8 +318,44 @@ namespace Tango.MachineStudio.Catalogs.ViewModels try { IsFree = false; + + //Validate color codes. + var duplicateCodes = ActiveCatalog + .ColorCatalogsGroups + .SelectMany(x => x.ColorCatalogsItems) + .GroupBy(x => x.Code) + .Where(x => x.Count() > 1) + .Select(x => x.First().Code) + .ToList(); + + if (duplicateCodes.Count > 0) + { + throw new InvalidOperationException($"Duplicate color codes found:\n{String.Join(Environment.NewLine, duplicateCodes)}"); + } + + //Validate color names. + var duplicateNames = ActiveCatalog + .ColorCatalogsGroups + .SelectMany(x => x.ColorCatalogsItems) + .GroupBy(x => x.Name) + .Where(x => x.Count() > 1) + .Select(x => x.First().Name) + .ToList(); + + if (duplicateNames.Count > 0) + { + throw new InvalidOperationException($"Duplicate color names found:\n{String.Join(Environment.NewLine, duplicateNames)}"); + } + + ActiveCatalog.LastUpdated = DateTime.UtcNow; await _activeCatalogContext.SaveChangesAsync(); + + var activeCatalogDTO = ColorCatalogDTO.FromObservable(ActiveCatalog); + _actionLogManager.InsertLog(ActionLogType.CatalogSaved, _authentication.CurrentUser, _catalogBeforeSave.Name, _catalogBeforeSave, activeCatalogDTO, "Catalog saved using Machine Studio."); + _catalogBeforeSave = activeCatalogDTO; + await LoadCatalogs(); + _notification.ShowInfo("Catalog updated successfully."); } catch (Exception ex) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Views/CatalogView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Views/CatalogView.xaml index ded1acb2d..5a49c93d3 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Views/CatalogView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Views/CatalogView.xaml @@ -13,7 +13,7 @@ xmlns:global="clr-namespace:Tango.MachineStudio.Catalogs" xmlns:local="clr-namespace:Tango.MachineStudio.Catalogs.Views" mc:Ignorable="d" - d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" Foreground="#232323" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" Foreground="{StaticResource DarkGrayBrush200}" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> @@ -51,7 +51,7 @@ 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/Controls/JobOutlineControl.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Controls/JobOutlineControl.cs index ee570ac34..68dc7e3bf 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Controls/JobOutlineControl.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Controls/JobOutlineControl.cs @@ -136,6 +136,34 @@ namespace Tango.MachineStudio.Developer.Controls _sizeControl.Height += NORMAL_FONT_HEIGHT; } } + //JobTicket.ThreadParameters + if (job.ThreadParameters != null) + { + _sizeControl.Height += 20; + DrawHeaderText(drawingContext, "THREAD PARAMETERS", 17, LevelOffset.level_0); + _sizeControl.Height += TITLE_FONT_HEIGHT; + _sizeControl.Height += 5.0; + basicProps = GetNameValueList(job.ThreadParameters); + foreach (var prop in basicProps) + { + DrawNameValueText(drawingContext, prop, LevelOffset.level_1, PackIconKind.Settings); + _sizeControl.Height += NORMAL_FONT_HEIGHT; + } + } + //JobTicket.HeadCleaningParameters + if (job.HeadCleaningParameters != null) + { + _sizeControl.Height += 20; + DrawHeaderText(drawingContext, "HEAD CLEANING PARAMETERS", 17, LevelOffset.level_0); + _sizeControl.Height += TITLE_FONT_HEIGHT; + _sizeControl.Height += 5.0; + basicProps = GetNameValueList(job.HeadCleaningParameters); + foreach (var prop in basicProps) + { + DrawNameValueText(drawingContext, prop, LevelOffset.level_1, PackIconKind.Settings); + _sizeControl.Height += NORMAL_FONT_HEIGHT; + } + } //JobTicket.Segments if (job.Segments != null) { 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 3a1f3fb11..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 @@ -50,6 +50,9 @@ using Tango.Core.ExtensionMethods; using Tango.ColorConversion; using Tango.PMR.Exports; using Microsoft.WindowsAPICodePack.Dialogs; +using Tango.BL.Enumerations; +using Tango.BL.DTO; +using Tango.BL.ActionLogs; namespace Tango.MachineStudio.Developer.ViewModels { @@ -85,6 +88,9 @@ namespace Tango.MachineStudio.Developer.ViewModels private TaskItem _preparingTaskItem; private IColorConverter _converter; private string _current_job_string; + private JobDTO _beforeSaveJobDTO; + private IActionLogManager _actionLogManager; + private RmlDTO _selectedRMLBeforeLiquidFactorsSaves; #region Properties @@ -747,7 +753,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// /// The application manager. /// The notification provider. - public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, INavigationManager navigationManager, IAuthenticationProvider authentication, IEventLogger eventLogger, ISpeechProvider speech) + public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, INavigationManager navigationManager, IAuthenticationProvider authentication, IEventLogger eventLogger, ISpeechProvider speech, IActionLogManager actionLogManager) { _converter = new DefaultColorConverter(); @@ -756,6 +762,7 @@ namespace Tango.MachineStudio.Developer.ViewModels AuthenticationProvider = authentication; + _actionLogManager = actionLogManager; _notification = notificationProvider; _speech = speech; _navigation = navigation; @@ -873,7 +880,7 @@ namespace Tango.MachineStudio.Developer.ViewModels foreach (var stop in stops) { - if (stop.ColorSpace.Code == BL.Enumerations.ColorSpaces.Volume.ToInt32() && !stop.IsLiquidVolumesOutOfRange) + if (stop.ColorSpace.Code == BL.Enumerations.ColorSpaces.Volume.ToInt32()) { try { @@ -1034,6 +1041,11 @@ namespace Tango.MachineStudio.Developer.ViewModels { var percent = (e.Progress / e.Total * 100d); + if (_preparingTaskItem != null) + { + _preparingTaskItem.Message = $"Preparing job for printing {(e.Progress / e.Total * 100d).ToString("0.0")}%..."; + } + if (_preparingTaskItem == null && percent == 0) { _preparingTaskItem = _notification.PushTaskItem("Preparing job for printing..."); @@ -1043,13 +1055,6 @@ namespace Tango.MachineStudio.Developer.ViewModels _preparingTaskItem.Pop(); _preparingTaskItem = null; } - else - { - if (_preparingTaskItem != null) - { - _preparingTaskItem.Message = $"Preparing job for printing {(e.Progress / e.Total * 100d).ToString("0.0")}%..."; - } - } } private void MachineOperator_ResumingJob(object sender, ResumingJobEventArgs e) @@ -1252,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 }; @@ -1371,7 +1376,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// /// Starts the job. /// - private async void StartJob(Func resumeFunc = null) + private async void StartJob(Func resumeFunc = null) { SettingsManager.Default.Save(); @@ -1436,15 +1441,13 @@ namespace Tango.MachineStudio.Developer.ViewModels } else { - JobHandler = resumeFunc(ActiveJob); + JobHandler = resumeFunc(); } _navigation.NavigateTo(DeveloperNavigationView.RunningJobView); IsJobRunning = true; ShowJobStatus = true; - _eventLogger.Log(String.Format("Job '{0}' started...", ActiveJob.Name)); - JobHandler.StatusChanged += (x, status) => { if (IsJobRunning) @@ -1464,25 +1467,21 @@ namespace Tango.MachineStudio.Developer.ViewModels if (!segment.IsInterSegment) { _speech.SpeakInfo(String.Format("Segment {0} Started.", segment.SegmentIndex)); - _eventLogger.Log(String.Format("Segment {0} Started.", segment.SegmentIndex) + Environment.NewLine + segment.ToJsonString()); } else { _speech.SpeakInfo(String.Format("Inter Segment Started.")); - _eventLogger.Log("Inter Segment Started."); } }; JobHandler.UnitCompleted += (x, unit) => { _speech.SpeakInfo(String.Format("{0} Units Completed.", unit + 1)); - _eventLogger.Log(String.Format("{0} Units Completed.", unit + 1)); }; JobHandler.Failed += (x, ex) => { LogManager.Log(ex, String.Format("Job {0} has failed.", RunningJob.Name)); - _eventLogger.Log(ex, String.Format("Job {0} has failed.", RunningJob.Name)); SetJobFailed(); InvokeUI(() => @@ -1496,13 +1495,11 @@ namespace Tango.MachineStudio.Developer.ViewModels { _speech.SpeakInfo("Finalizing job..."); LogManager.Log(String.Format("Finalizing job {0}.", RunningJob.Name)); - _eventLogger.Log(String.Format("Finalizing job {0}.", RunningJob.Name)); }; JobHandler.Completed += (x, e) => { LogManager.Log(String.Format("Job {0} has completed.", RunningJob.Name)); - _eventLogger.Log(String.Format("Job {0} has completed.", RunningJob.Name)); SetJobCompleted(); StopRecordingIfInProgress(); }; @@ -1516,7 +1513,6 @@ namespace Tango.MachineStudio.Developer.ViewModels } LogManager.Log(String.Format("Job {0} has been canceled.", RunningJob.Name)); - _eventLogger.Log(String.Format("Job {0} has been canceled.", RunningJob.Name)); StopRecordingIfInProgress(); //Finally Canceled.. }; @@ -1534,7 +1530,6 @@ namespace Tango.MachineStudio.Developer.ViewModels catch (Exception ex) { LogManager.Log(ex); - _eventLogger.Log(ex, "An error occurred while starting the job."); _notification.ShowError("An error occurred while starting the job. " + Environment.NewLine + ex.Message); SetJobFailed(); StopRecordingIfInProgress(); @@ -1594,8 +1589,12 @@ namespace Tango.MachineStudio.Developer.ViewModels { LogManager.Log(String.Format("Saving liquid factors for RML {0}...", SelectedRML.Name)); await SelectedRML.SaveAsync(_activeJobDbContext); + var rmlAfterChange = RmlDTO.FromObservable(SelectedRML); + _actionLogManager.InsertLog(ActionLogType.RmlSaved, AuthenticationProvider.CurrentUser, SelectedRML.Name, _selectedRMLBeforeLiquidFactorsSaves, rmlAfterChange, "RML liquid factors changed from Machine Studio Research module."); + _selectedRMLBeforeLiquidFactorsSaves = rmlAfterChange; LiquidTypesRmls = ActiveJob.Machine.Configuration.GetSupportedIdsPacks(SelectedRML).Select(x => x.LiquidType).SelectMany(x => x.LiquidTypesRmls).Where(x => x.Rml.Guid == SelectedRML.Guid).ToList(); + foreach (var segment in ActiveJob.Segments) { SetSegmentBrushStopsLiquidVolumes(segment); @@ -1623,7 +1622,9 @@ namespace Tango.MachineStudio.Developer.ViewModels { LogManager.Log("Invalidating liquid factors, process parameters and process group history..."); - _selectedRML = new RmlBuilder(_activeJobDbContext).Set(SelectedRML.Guid).WithAllParametersGroup().WithCAT(SelectedMachine.Guid).WithCCT().WithLiquidFactors().Build(); + _selectedRML = new RmlBuilder(_activeJobDbContext).Set(SelectedRML.Guid).WithAllParametersGroup().WithCAT(SelectedMachine.Guid).WithCCT().WithLiquidFactors().WithSpools().Build(); + + _selectedRMLBeforeLiquidFactorsSaves = RmlDTO.FromObservable(_selectedRML); if (_selectedRML.Cct == null) { @@ -1672,7 +1673,17 @@ namespace Tango.MachineStudio.Developer.ViewModels { await Task.Factory.StartNew(() => { - InvalidateLiquidFactorsAndProcessTables(); + try + { + IsFree = false; + InvalidateLiquidFactorsAndProcessTables(); + } + catch + {} + finally + { + IsFree = true; + } }); } } @@ -1680,6 +1691,23 @@ namespace Tango.MachineStudio.Developer.ViewModels #endregion + #region Color Space + + public void OnBrushStopColorSpaceChanged(BrushStop stop) + { + if (stop != null && stop.ColorSpace != null && stop.BrushColorSpace != BL.Enumerations.ColorSpaces.Volume) + { + var lubricant = stop.LiquidVolumes.SingleOrDefault(x => x.LiquidType == LiquidTypes.Lubricant); + + if (lubricant != null) + { + lubricant.Volume = 100; + } + } + } + + #endregion + #region Process Parameters Management /// @@ -1691,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); } } @@ -1715,6 +1743,8 @@ namespace Tango.MachineStudio.Developer.ViewModels using (_notification.PushTaskItem("Saving Parameters Group...")) { + var processGroupBefore = ProcessParametersTablesGroupDTO.FromObservable(SelectedRML.GetActiveProcessGroup()); + using (var db = ObservablesContext.CreateDefault()) { var active_groups = db.ProcessParametersTablesGroups.Where(x => x.RmlGuid == SelectedRML.Guid && x.Active).ToList(); @@ -1756,6 +1786,8 @@ namespace Tango.MachineStudio.Developer.ViewModels SelectedRML.ProcessParametersTablesGroups.Add(group); await SelectedRML.SaveAsync(_activeJobDbContext); + _actionLogManager.InsertLog(ActionLogType.RmlActiveProcessParametersChanged, AuthenticationProvider.CurrentUser, SelectedRML.Name, processGroupBefore, ProcessParametersTablesGroupDTO.FromObservable(SelectedRML.GetActiveProcessGroup()), "RML Active process parameters changed from Machine Studio Research module."); + InvalidateLiquidFactorsAndProcessTables(); } @@ -1800,97 +1832,110 @@ namespace Tango.MachineStudio.Developer.ViewModels using (_notification.PushTaskItem("Loading job details...")) { - await Task.Factory.StartNew(() => + try { - _disable_gamut_check = true; + await Task.Factory.StartNew(() => + { + _disable_gamut_check = true; - LogManager.Log(String.Format("Loading job {0}...", SelectedMachineJob.Name)); - SelectedSegments = new ObservableCollection(); - SelectedBrushStops = new ObservableCollection(); - SelectedRML = null; - SelectedSegment = null; - SelectedGroupHistory = null; - SelectedBrushStop = null; - SelectedProcessParametersTable = null; - RmlProcessParametersTableGroup = null; + LogManager.Log(String.Format("Loading job {0}...", SelectedMachineJob.Name)); + SelectedSegments = new ObservableCollection(); + SelectedBrushStops = new ObservableCollection(); + SelectedRML = null; + SelectedSegment = null; + SelectedGroupHistory = null; + SelectedBrushStop = null; + SelectedProcessParametersTable = null; + RmlProcessParametersTableGroup = null; - _blockInvalidateCommands = false; + _blockInvalidateCommands = false; - LogManager.Log("Creating active job DB context..."); - _activeJobDbContext = ObservablesContext.CreateDefault(); + LogManager.Log("Creating active job DB context..."); + _activeJobDbContext = ObservablesContext.CreateDefault(); - LogManager.Log("Initializing available color spaces, RMLs & Winding methods..."); + LogManager.Log("Initializing available color spaces, RMLs & Winding methods..."); - //var processParamsGroups = _activeJobDbContext.ProcessParametersTablesGroups.ToList(); - //var processParams = _activeJobDbContext.ProcessParametersTables.ToList(); + //var processParamsGroups = _activeJobDbContext.ProcessParametersTablesGroups.ToList(); + //var processParams = _activeJobDbContext.ProcessParametersTables.ToList(); - ColorSpaces = _activeJobDbContext.ColorSpaces.ToObservableCollection(); - Rmls = _activeJobDbContext.Rmls.ToObservableCollection(); - WindingMethods = _activeJobDbContext.WindingMethods.ToObservableCollection(); - SpoolTypes = _activeJobDbContext.SpoolTypes.ToObservableCollection(); + ColorSpaces = _activeJobDbContext.ColorSpaces.ToObservableCollection(); + Rmls = _activeJobDbContext.Rmls.OrderBy(i => i.Name).ToObservableCollection(); + WindingMethods = _activeJobDbContext.WindingMethods.ToObservableCollection(); + SpoolTypes = _activeJobDbContext.SpoolTypes.ToObservableCollection(); - LogManager.Log("Loading machine spools..."); - _activeJobDbContext.Spools.Where(x => x.MachineGuid == SelectedMachine.Guid).Load(); + LogManager.Log("Loading machine spools..."); + _activeJobDbContext.Spools.Where(x => x.MachineGuid == SelectedMachine.Guid).Load(); - LogManager.Log("Setting active job..."); - ActiveJob = new JobBuilder(_activeJobDbContext).Set(SelectedMachineJob.Guid).WithUser().WithSegments().WithBrushStops().WithConfiguration().WithRML().Build(); + LogManager.Log("Setting active job..."); + ActiveJob = new JobBuilder(_activeJobDbContext).Set(SelectedMachineJob.Guid).WithUser().WithSegments().WithBrushStops().WithConfiguration().WithRML().Build(); - //_activeJobDbContext.Ccts.Where(x => x.RmlGuid == ActiveJob.RmlGuid).ToList(); - //_activeJobDbContext.Cats.Where(x => x.RmlGuid == ActiveJob.RmlGuid).ToList(); - //_activeJobDbContext.Machines.SingleOrDefault(x => x.Guid == ActiveJob.MachineGuid); - //_activeJobDbContext.Configurations.SingleOrDefault(x => x.Guid == ActiveJob.Machine.ConfigurationGuid); + //_activeJobDbContext.Ccts.Where(x => x.RmlGuid == ActiveJob.RmlGuid).ToList(); + //_activeJobDbContext.Cats.Where(x => x.RmlGuid == ActiveJob.RmlGuid).ToList(); + //_activeJobDbContext.Machines.SingleOrDefault(x => x.Guid == ActiveJob.MachineGuid); + //_activeJobDbContext.Configurations.SingleOrDefault(x => x.Guid == ActiveJob.Machine.ConfigurationGuid); - //_activeJobDbContext.LiquidTypesRmls.ToList(); + //_activeJobDbContext.LiquidTypesRmls.ToList(); - //_activeJobDbContext.IdsPackFormulas.ToList(); - //_activeJobDbContext.LiquidTypes.ToList(); - //_activeJobDbContext.MidTankTypes.ToList(); - //_activeJobDbContext.DispenserTypes.ToList(); + //_activeJobDbContext.IdsPackFormulas.ToList(); + //_activeJobDbContext.LiquidTypes.ToList(); + //_activeJobDbContext.MidTankTypes.ToList(); + //_activeJobDbContext.DispenserTypes.ToList(); - //_activeJobDbContext.IdsPacks.Where(x => x.ConfigurationGuid == ActiveJob.Machine.ConfigurationGuid).ToList(); + //_activeJobDbContext.IdsPacks.Where(x => x.ConfigurationGuid == ActiveJob.Machine.ConfigurationGuid).ToList(); + _beforeSaveJobDTO = JobDTO.FromObservable(ActiveJob); - LogManager.Log("Setting selected segment..."); - _selectedSegment = ActiveJob.OrderedSegments.FirstOrDefault(); + LogManager.Log("Setting selected segment..."); + _selectedSegment = ActiveJob.OrderedSegments.FirstOrDefault(); - ActiveJob.LengthChanged -= ActiveJob_LengthChanged; - ActiveJob.LengthChanged += ActiveJob_LengthChanged; + ActiveJob.LengthChanged -= ActiveJob_LengthChanged; + ActiveJob.LengthChanged += ActiveJob_LengthChanged; - _selectedRML = ActiveJob.Rml; - InvalidateLiquidFactorsAndProcessTables(); - RaisePropertyChanged(nameof(SelectedRML)); + _selectedRML = ActiveJob.Rml; + InvalidateLiquidFactorsAndProcessTables(); + RaisePropertyChanged(nameof(SelectedRML)); - UpdateEstimatedDuration(); + UpdateEstimatedDuration(); - _blockInvalidateCommands = false; - InvalidateRelayCommands(); + _blockInvalidateCommands = false; + InvalidateRelayCommands(); - _disable_gamut_check = false; + _disable_gamut_check = false; - _settings.LastSelectedMachineGuid = SelectedMachine != null ? SelectedMachine.Guid : null; - _settings.LastSelectedJobGuid = SelectedMachineJob != null ? SelectedMachineJob.Guid : null; + _settings.LastSelectedMachineGuid = SelectedMachine != null ? SelectedMachine.Guid : null; + _settings.LastSelectedJobGuid = SelectedMachineJob != null ? SelectedMachineJob.Guid : null; - _settings.Save(); - }); + _settings.Save(); + }); - SegmentsCollectionView = CollectionViewSource.GetDefaultView(ActiveJob.Segments); - SegmentsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Segment.SegmentIndex), ListSortDirection.Ascending)); + SegmentsCollectionView = CollectionViewSource.GetDefaultView(ActiveJob.Segments); + SegmentsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Segment.SegmentIndex), ListSortDirection.Ascending)); - foreach (var segment in ActiveJob.Segments) - { - SetSegmentBrushStopsLiquidVolumes(segment); - } + foreach (var segment in ActiveJob.Segments) + { + SetSegmentBrushStopsLiquidVolumes(segment); + } - SelectedSegment = _selectedSegment; + SelectedSegment = _selectedSegment; + + if (ActiveJob != null) + { + _current_job_string = ActiveJob.ToJobFileWhenLoaded().ToString(); + } - if (ActiveJob != null) + UIHelper.DoEvents(); + _navigation.NavigateTo(DeveloperNavigationView.JobView); + } + catch (Exception ex) { - _current_job_string = ActiveJob.ToJobFileWhenLoaded().ToString(); + LogManager.Log(ex, "Error loading job."); + _notification.ShowError($"An error occurred while trying to load the selected job.\n{ex.FlattenMessage()}"); + } + finally + { + CanWork = true; } - - UIHelper.DoEvents(); - _navigation.NavigateTo(DeveloperNavigationView.JobView); } CanWork = true; @@ -1908,50 +1953,65 @@ namespace Tango.MachineStudio.Developer.ViewModels { CanWork = false; - using (_notification.PushTaskItem("Saving job details...")) + try { - await Task.Factory.StartNew(() => + using (_notification.PushTaskItem("Saving job details...")) { - LogManager.Log(String.Format("Saving the active job {0}...", ActiveJob.Name)); - ActiveJob.LastUpdated = DateTime.UtcNow; - ActiveJob.Rml = SelectedRML; - ActiveJob.EstimatedDurationMili = (int)EstimatedDuration.TotalMilliseconds; - _activeJobDbContext.SaveChanges(); - - _machineDbContext.Entry(SelectedMachineJob).Reload(); + await Task.Factory.StartNew(() => + { + LogManager.Log(String.Format("Saving the active job {0}...", ActiveJob.Name)); + ActiveJob.LastUpdated = DateTime.UtcNow; + ActiveJob.IsSynchronized = false; + ActiveJob.Rml = SelectedRML; + ActiveJob.EstimatedDurationMili = (int)EstimatedDuration.TotalMilliseconds; + ActiveJob.MarkModified(_activeJobDbContext); + _activeJobDbContext.SaveChanges(); + var afterJobDTO = JobDTO.FromObservable(ActiveJob); + _actionLogManager.InsertLog(ActionLogType.JobSaved, AuthenticationProvider.CurrentUser, _beforeSaveJobDTO.Name, _beforeSaveJobDTO, afterJobDTO, "Job saved from research module in Machine Studio."); + _beforeSaveJobDTO = afterJobDTO; - _machineDbContext.Entry(SelectedMachineJob).Collection(x => x.Segments).Load(); + _machineDbContext.Entry(SelectedMachineJob).Reload(); - foreach (var segment in SelectedMachineJob.Segments.ToList()) - { - _machineDbContext.Entry(segment).Collection(x => x.BrushStops).Load(); + _machineDbContext.Entry(SelectedMachineJob).Collection(x => x.Segments).Load(); - foreach (var brushStop in segment.BrushStops.ToList()) + foreach (var segment in SelectedMachineJob.Segments.ToList()) { - _machineDbContext.Entry(brushStop).Reload(); - } + _machineDbContext.Entry(segment).Collection(x => x.BrushStops).Load(); - _machineDbContext.Entry(segment).Reload(); - } + foreach (var brushStop in segment.BrushStops.ToList()) + { + _machineDbContext.Entry(brushStop).Reload(); + } - InvokeUI(() => - { - SelectedMachineJob.Segments = SelectedMachineJob.Segments; - }); + _machineDbContext.Entry(segment).Reload(); + } - var settings = SettingsManager.Default.GetOrCreate(); - settings.DefaultJobRmlGuid = ActiveJob.RmlGuid; - settings.Save(); + InvokeUI(() => + { + SelectedMachineJob.Segments = SelectedMachineJob.Segments; + }); - if (ActiveJob != null) - { - _current_job_string = ActiveJob.ToJobFileWhenLoaded().ToString(); - } - }); - } + var settings = SettingsManager.Default.GetOrCreate(); + settings.DefaultJobRmlGuid = ActiveJob.RmlGuid; + settings.Save(); - CanWork = true; + if (ActiveJob != null) + { + _current_job_string = ActiveJob.ToJobFileWhenLoaded().ToString(); + } + }); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving active job."); + _notification.ShowError($"An error occurred while trying to save the current job.\n{ex.FlattenMessage()}"); + } + finally + { + CanWork = true; + } } } @@ -2139,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"; @@ -2171,6 +2231,8 @@ namespace Tango.MachineStudio.Developer.ViewModels { if (_notification.ShowQuestion("Are you sure you want to delete the selected jobs?")) { + var jobsToReport = SelectedJobs.Select(x => JobDTO.FromObservable(x)).ToList(); + LogManager.Log(String.Format("Removing {0} jobs...", SelectedJobs.Count)); SelectedJobs.ToList().ForEach(x => { @@ -2182,6 +2244,11 @@ namespace Tango.MachineStudio.Developer.ViewModels LogManager.Log("Saving selected machine to database..."); await SelectedMachine.SaveAsync(_machineDbContext); } + + foreach (var job in jobsToReport) + { + _actionLogManager.InsertLog(ActionLogType.JobDeleted, AuthenticationProvider.CurrentUser, job.Name, job, "Job deleted using Machine Studio.", true); + } } } } @@ -2202,6 +2269,8 @@ namespace Tango.MachineStudio.Developer.ViewModels var settings = SettingsManager.Default.GetOrCreate(); Job newJob = new Job(); + newJob.LastUpdated = DateTime.UtcNow; + newJob.JobSource = JobSource.Remote; newJob.Name = jobName; newJob.CreationDate = DateTime.UtcNow; newJob.UserGuid = AuthenticationProvider.CurrentUser.Guid; @@ -2236,6 +2305,7 @@ namespace Tango.MachineStudio.Developer.ViewModels LogManager.Log("Saving selected machine to database..."); await SelectedMachine.SaveAsync(_machineDbContext); + _actionLogManager.InsertLog(ActionLogType.JobCreated, AuthenticationProvider.CurrentUser, newJob.Name, newJob, "Job created using Machine Studio."); SelectedMachineJob = newJob; LoadSelectedJob(); } @@ -2261,6 +2331,13 @@ namespace Tango.MachineStudio.Developer.ViewModels return; } SelectedSegment.BrushStops.Remove(x); + var existingBrushStop = _activeJobDbContext.BrushStops.FirstOrDefault(y => y.Guid == x.Guid); + if(existingBrushStop != null) + { + _activeJobDbContext.BrushStops.Remove(existingBrushStop); + } + + }); ArrangeBrushStopsIndices(); @@ -2275,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(); @@ -2295,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(); } @@ -2305,7 +2383,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// 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)) { @@ -2323,7 +2401,7 @@ namespace Tango.MachineStudio.Developer.ViewModels /// private void DuplicateSelectedSegments() { - LogManager.LogFormat("Duplicating {0} segments...", SelectedSegments.Count); + LogManager.Log($"Duplicating {SelectedSegments.Count} segments..."); int start_index = SelectedSegments.Max(x => x.SegmentIndex); @@ -2351,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); @@ -2365,6 +2443,11 @@ namespace Tango.MachineStudio.Developer.ViewModels LogManager.Log("Saving selected machine to database..."); await SelectedMachine.SaveAsync(_machineDbContext); + foreach (var job in SelectedJobs) + { + _actionLogManager.InsertLog(ActionLogType.JobCreated, AuthenticationProvider.CurrentUser, job.Name, job, "Job cloned using Machine Studio."); + } + CanWork = true; } } @@ -2588,17 +2671,26 @@ namespace Tango.MachineStudio.Developer.ViewModels LogManager.Log($"Importing job files..."); + List jobsToReport = new List(); + foreach (var file in dlg.FileNames) { var bytes = File.ReadAllBytes(file); var jobFile = JobFile.Parser.ParseFrom(bytes); var job = await Job.FromJobFile(jobFile, SelectedMachine.Guid, AuthenticationProvider.CurrentUser.Guid); + job.JobSource = JobSource.Remote; _machineDbContext.Jobs.Add(job); + jobsToReport.Add(job); } await _machineDbContext.SaveChangesAsync(); + foreach (var job in jobsToReport) + { + _actionLogManager.InsertLog(ActionLogType.JobImported, AuthenticationProvider.CurrentUser, job.Name, job, "Job imported using Machine Studio."); + } + IsFree = true; _notification.ShowInfo($"Jobs imported successfully."); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml index f0e9dc29c..c0cb963e7 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml @@ -5,8 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:vm="clr-namespace:Tango.MachineStudio.Developer.ViewModels" xmlns:local="clr-namespace:Tango.MachineStudio.Developer.Views" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" - Height="450" Width="800" Background="{StaticResource WhiteBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:InsufficientLiquidQuantityViewVM, IsDesignTimeCreatable=False}"> + Height="590" Width="800" d:DataContext="{d:DesignInstance Type=vm:InsufficientLiquidQuantityViewVM, IsDesignTimeCreatable=False}" Foreground="{StaticResource Dialog.Foreground}" + Background="{StaticResource Dialog.Background}"> @@ -23,28 +25,60 @@ - - + + - + - - - + + + + + + + + + + + + + + - + - - + + - + + + + + + + + + - + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml.cs index 171cb754e..51cfb1e73 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/InsufficientLiquidQuantityView.xaml.cs @@ -33,7 +33,7 @@ namespace Tango.MachineStudio.Developer.Views Grid parent = border.Parent as Grid; IDSPackLevel packLevel = border.DataContext as IDSPackLevel; - border.Height = ((double)packLevel.Current / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualHeight; + border.Width = ((double)packLevel.Current / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualWidth; } private void Limit_Loaded(object sender, RoutedEventArgs e) @@ -42,8 +42,8 @@ namespace Tango.MachineStudio.Developer.Views Grid parent = rect.Parent as Grid; IDSPackLevel packLevel = rect.DataContext as IDSPackLevel; - var top = ((double)packLevel.Required / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualHeight; - rect.Margin = new Thickness(0, 0, 0, top); + var left = ((double)packLevel.Required / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualWidth; + rect.Margin = new Thickness(left, 0, 0, 0); if (packLevel.IsValid) { 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 3bda86036..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 @@ -28,7 +28,8 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Tango.MachineStudio.Developer.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}" x:Name="control"> + d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" + DataContext="{x:Static global:ViewModelLocator.MainViewVM}" x:Name="control"> @@ -241,91 +242,93 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Liquid volumes exceeds the maximum range for color conversion! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - + Total: % ( nl ) - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + Liquid volumes exceeds the maximum range for color conversion! + @@ -677,7 +680,7 @@ - + @@ -753,7 +756,7 @@ MEDIA - + @@ -768,7 +771,7 @@ - + + + Setup Activation + + + Setup Remote Assistance + + + Setup UWF + + + Setup Firmware + + + Setup FPGA + + + Is Demo Machine + + + Suspend Version Update + + + Force Version Update + + + Update Schema on Update + + + + + + + + + Device Registration + + Device ID: + + + + Device Name: + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml new file mode 100644 index 000000000..0e793dc6a --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml.cs new file mode 100644 index 000000000..8bb051c51 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.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.MachineDesigner.Views +{ + /// + /// Interaction logic for MachineCreationDialog.xaml + /// + public partial class MachineUpdateDetailsDialog : UserControl + { + public MachineUpdateDetailsDialog() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml new file mode 100644 index 000000000..bd272718d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Machine Setups + Software Updates + Database Updates + Synchronizations + Offline Updates + Offline Firmware Upgrades + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml.cs new file mode 100644 index 000000000..d13ef2d0e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.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.MachineDesigner.Views +{ + /// + /// Interaction logic for SpoolsView.xaml + /// + public partial class MachineUpdatesView : UserControl + { + public MachineUpdatesView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachinesView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachinesView.xaml index 35b578b6a..a231e92a3 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachinesView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachinesView.xaml @@ -15,6 +15,7 @@ d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + @@ -73,7 +74,8 @@ - + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml index bc9b038dc..833086bf0 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml @@ -9,7 +9,7 @@ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" 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}"> - + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/SpoolsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/SpoolsView.xaml index 3663f72f8..f08da88d1 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/SpoolsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/SpoolsView.xaml @@ -9,8 +9,14 @@ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" mc:Ignorable="d" d:DesignHeight="720" d:DesignWidth="1280" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + + + + + @@ -67,10 +73,7 @@ - - - - + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml new file mode 100644 index 000000000..895a26ca0 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + Create a complete update package (.tup) in order to update this machine offline using a removable storage device. + + The latest PPC version is + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs new file mode 100644 index 000000000..fe01296d8 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.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.MachineDesigner.Views +{ + /// + /// Interaction logic for SpoolsView.xaml + /// + public partial class TupView : UserControl + { + public TupView() + { + InitializeComponent(); + } + } +} 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 TargetLiquidTypeToLAB = new Dictionary + { + {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 DisplayLiquidTypeToLABType = new Dictionary + { + {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 items, ref string errors) + { + items = null; + try + { + using (ExcelReader reader = new ExcelReader(fileName)) + { + items = reader.GetDataByIndex("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 2ff9ab0a3..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 @@ ..\..\..\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll + + ..\..\..\packages\OxyPlot.Core.2.0.0\lib\net45\OxyPlot.dll + + + ..\..\..\packages\OxyPlot.Wpf.2.0.0\lib\net45\OxyPlot.Wpf.dll + @@ -73,7 +79,9 @@ GlobalVersionInfo.cs + + Code @@ -93,16 +101,21 @@ + + AddLiquidFactorView.xaml CalibrationDataView.xaml + + ColorCalibrationView.xaml + ColorConversionView.xaml @@ -112,12 +125,24 @@ ProcessParametersView.xaml + + RmlDeleteDialogView.xaml + RmlsView.xaml RmlView.xaml + + HeadCleaningParametersView.xaml + + + ThreadParametersView.xaml + + + SpoolsView.xaml + ResXFileCodeGenerator Resources.Designer.cs @@ -142,6 +167,10 @@ {40085232-aced-4cbe-945b-90ba8153c151} Tango.BrushPicker + + {b60c695c-61e8-4091-b506-4c45349c04aa} + Tango.ColorCalibration + {b4fe6485-4161-4b36-bc08-67e0b53d01b7} Tango.ColorConversion @@ -203,6 +232,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -215,6 +248,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -223,6 +260,18 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + 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 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 _liquidTypes; + + public List LiquidTypes + { + get { return _liquidTypes; } + set { _liquidTypes = value; } + } + + + private ObservableCollection _measurements; + public ObservableCollection 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 _points; + /// + /// Binding to ItemsSource of line chart. + /// + public IList Points + { + get { return _points; } + set + { + _points = value; + RaisePropertyChangedAuto(); + } + } + private IList _targetPoints; + /// + /// Binding to ItemsSource of line chart. + /// + public IList TargetPoints + { + get { return _targetPoints; } + set + { + _targetPoints = value; + RaisePropertyChangedAuto(); + } + } + private int _step; + public int XStep + { + get { return _step; } + set { _step = value; RaisePropertyChangedAuto(); } + } + + private double _from; + /// + /// From use to binding to bottom axis min value + /// + public double From + { + get { return _from; } + set + { + _from = value; RaisePropertyChangedAuto(); + } + } + + private double _to; + /// + /// To use to binding to bottom axis max value + /// + 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 _linearizationPoints; + /// + /// Binding to ItemsSource of line chart. + /// + public IList LinearizationPoints + { + get { return _linearizationPoints; } + set + { + _linearizationPoints = value; + RaisePropertyChangedAuto(); + } + } + + private IList _LPoints; + + public IList LPoints + { + get { return _LPoints; } + set { _LPoints = value; } + } + + private IList _APoints; + + public IList APoints + { + get { return _APoints; } + set { _APoints = value; } + } + + private IList _BPoints; + + public IList BPoints + { + get { return _BPoints; } + set { _BPoints = value; } + } + + + #endregion + + public ColorCalibrationViewVM(INotificationProvider notification) + { + _notification = notification; + Measurements = new ObservableCollection() + { + 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(); + TargetPoints = new List(); + LinearizationPoints = new List(); + LPoints = new List(); + APoints = new List(); + BPoints = new List(); + } + + 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 items;//List 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 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 outputPoints = new List(); + + 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); + } + + /// + /// Open file dialog and get name of file + /// + /// + 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 GetLinearizationMeasurements(List 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 + /// + /// Exports the graph point to Excel file. + /// + 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 points = new List(); + 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, + }; + } + + /// + /// Applies the calibration data. + /// + protected void ApplyCalibrationData() + { + if (LinearizationPoints.Count == 0) + return; + + List points = new List(); + 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 b68239b4b..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,6 +310,19 @@ namespace Tango.MachineStudio.RML.ViewModels } } + private double GetTotalMaximumLiquidNlPerCMLimit() + { + try + { + var tables = RML.GetActiveProcessGroup().ProcessParametersTables.OrderBy(x => x.TableIndex).ToList(); + return tables.Max(x => x.MaxInkUptake); + } + catch + { + return BrushStop.MAX_INK_UPTAKE; + } + } + private void OnLiquidVolumeChanged() { try @@ -316,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) > 200) + 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 ee21b9ac3..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 @@ -21,12 +21,19 @@ using Tango.MachineStudio.RML.Views; using Tango.PMR.ColorLab; using System.Data.Entity; using Tango.Core.ExtensionMethods; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.ActionLogs; +using Tango.BL.DTO; +using Tango.BL.Enumerations; namespace Tango.MachineStudio.RML.ViewModels { public class MainViewVM : StudioViewModel { private INotificationProvider _notification; + private IAuthenticationProvider _authentication; + private IActionLogManager _actionLogManager; + private RmlDTO _rmlBeforeSave; private ObservablesContext _rmls_context; private ObservablesContext _active_context; @@ -38,6 +45,20 @@ namespace Tango.MachineStudio.RML.ViewModels set { _rmls = value; RaisePropertyChangedAuto(); } } + private ICollectionView _rmlssCollectionView; + /// + /// Gets or sets the RML collection view. + /// + public ICollectionView RmlsCollectionView + { + get { return _rmlssCollectionView; } + set + { + _rmlssCollectionView = value; + RaisePropertyChangedAuto(); + } + } + private ObservableCollection _materials; public ObservableCollection Materials { @@ -80,6 +101,13 @@ namespace Tango.MachineStudio.RML.ViewModels set { _fiberSynths = value; RaisePropertyChangedAuto(); } } + private ObservableCollection _spoolTypes; + public ObservableCollection SpoolTypes + { + get { return _spoolTypes; } + set { _spoolTypes = value; RaisePropertyChangedAuto(); } + } + private Rml _selectedRML; public Rml SelectedRML { @@ -143,6 +171,30 @@ namespace Tango.MachineStudio.RML.ViewModels set { _colorConversionViewVM = value; RaisePropertyChangedAuto(); } } + private RmlsSpool _selectedSpool; + public RmlsSpool SelectedSpool + { + get { return _selectedSpool; } + set { _selectedSpool = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private ColorCalibrationViewVM _colorCalibrationVM; + public ColorCalibrationViewVM ColorCalibrationVM + { + get { return _colorCalibrationVM; } + set { _colorCalibrationVM = value; RaisePropertyChangedAuto(); } + } + + private String _RMLFilter; + /// + /// Gets or sets the job filter. + /// + public String RMLFilter + { + get { return _RMLFilter; } + set { _RMLFilter = value; RaisePropertyChangedAuto(); OnRMLFilterChanged(); } + } + /// /// Gets or sets the manage RML command. /// @@ -185,9 +237,21 @@ namespace Tango.MachineStudio.RML.ViewModels public RelayCommand ImportRMLFileCommand { get; set; } - public MainViewVM(INotificationProvider notificationProvider) + /// + /// Gets or sets the add spool command. + /// + public RelayCommand AddSpoolCommand { get; set; } + + /// + /// Gets or sets the remove spool command. + /// + public RelayCommand RemoveSpoolCommand { get; set; } + + public MainViewVM(INotificationProvider notificationProvider, IAuthenticationProvider authentication, IActionLogManager actionLogManager) { _notification = notificationProvider; + _authentication = authentication; + _actionLogManager = actionLogManager; ManageRmlCommand = new RelayCommand(() => LoadActiveRML(SelectedRML.Guid), () => SelectedRML != null); RemoveRmlCommand = new RelayCommand(RemoveSelectedRml, () => SelectedRML != null); CloneRmlCommand = new RelayCommand(CloneSelectedRml, () => SelectedRML != null); @@ -206,6 +270,9 @@ namespace Tango.MachineStudio.RML.ViewModels ExportRMLFileCommand = new RelayCommand(ExportRmlFile, () => SelectedRML != null && IsFree); ImportRMLFileCommand = new RelayCommand(ImportRmlFile, () => IsFree); + + AddSpoolCommand = new RelayCommand(AddNewSpool); + RemoveSpoolCommand = new RelayCommand(RemoveSpool, () => SelectedSpool != null); } public override void OnApplicationReady() @@ -215,130 +282,177 @@ 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(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) { using (_notification.PushTaskItem("Loading RML...")) { - IsFree = false; - - if (_active_context != null) + try { - _active_context.Dispose(); - } - - _active_context = ObservablesContext.CreateDefault(); + IsFree = false; - CCTS = _active_context.Ccts - .Select(x => new CctModel() + if (_active_context != null) { - Guid = x.Guid, - FileName = x.FileName, + _active_context.Dispose(); + } - }).ToObservableCollection(); + _active_context = ObservablesContext.CreateDefault(); - CCTS.Where(x => String.IsNullOrWhiteSpace(x.FileName)).ToList().ForEach(x => x.FileName = x.Guid); + CCTS = _active_context.Ccts + .Select(x => new CctModel() + { + Guid = x.Guid, + FileName = x.FileName, - LoadRmlProperties(); + }).ToObservableCollection(); - ActiveRML = await new RmlBuilder(_active_context) - .Set(guid) - .WithActiveParametersGroup() - .WithLiquidFactors() - .WithCCT() - .BuildAsync(); + CCTS.Where(x => String.IsNullOrWhiteSpace(x.FileName)).ToList().ForEach(x => x.FileName = x.Guid); - if (ActiveRML.Cct != null) - { - SelectedCCT = CCTS.SingleOrDefault(x => x.Guid == ActiveRML.Cct.Guid); - } + LoadRmlProperties(); - if (ActiveRML.ProcessParametersTablesGroups.ToList().Count == 0) - { - if (!_notification.ShowQuestion("Could not find any process group for the selected RML. Would you like to create one?")) + ActiveRML = await new RmlBuilder(_active_context) + .Set(guid) + .WithActiveParametersGroup() + .WithLiquidFactors() + .WithCCT() + .WithSpools() + .BuildAsync(); + + if (ActiveRML.Cct != null) { - _notification.ShowError("Cannot load an RML with no process group."); - IsFree = true; - return; + SelectedCCT = CCTS.SingleOrDefault(x => x.Guid == ActiveRML.Cct.Guid); } - else + + if (ActiveRML.ProcessParametersTablesGroups.ToList().Count == 0) { - ProcessParametersTablesGroup group = new ProcessParametersTablesGroup(); - group.Name = "Active Group"; - group.Active = true; - group.ProcessParametersTables.Add(new ProcessParametersTable() + if (!_notification.ShowQuestion("Could not find any process group for the selected RML. Would you like to create one?")) + { + _notification.ShowError("Cannot load an RML with no process group."); + IsFree = true; + return; + } + else { - Name = "Process Table 1", - }); + ProcessParametersTablesGroup group = new ProcessParametersTablesGroup(); + group.Name = "Active Group"; + group.Active = true; + group.ProcessParametersTables.Add(new ProcessParametersTable() + { + Name = "Process Table 1", + }); - group.Rml = ActiveRML; + group.Rml = ActiveRML; - _active_context.ProcessParametersTablesGroups.Add(group); - _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]); - await _active_context.SaveChangesAsync(); - LoadActiveRML(ActiveRML.Guid); - return; + _active_context.ProcessParametersTablesGroups.Add(group); + _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]); + await _active_context.SaveChangesAsync(); + LoadActiveRML(ActiveRML.Guid); + return; + } } - } - ActiveProcessParametersGroup = ActiveRML.ProcessParametersTablesGroups.ToList().FirstOrDefault(); - ActiveProcessParametersTableView = CollectionViewSource.GetDefaultView(ActiveProcessParametersGroup.ProcessParametersTables); - ActiveProcessParametersTableView.SortDescriptions.Add(new SortDescription(nameof(ProcessParametersTable.TableIndex), ListSortDirection.Ascending)); + ActiveProcessParametersGroup = ActiveRML.ProcessParametersTablesGroups.ToList().FirstOrDefault(); + ActiveProcessParametersTableView = CollectionViewSource.GetDefaultView(ActiveProcessParametersGroup.ProcessParametersTables); + ActiveProcessParametersTableView.SortDescriptions.Add(new SortDescription(nameof(ProcessParametersTable.TableIndex), ListSortDirection.Ascending)); - CalibrationDataViewVM = new CalibrationDataViewVM(_notification); - LiquidTypesRmls = ActiveRML.LiquidTypesRmls; + CalibrationDataViewVM = new CalibrationDataViewVM(_notification); + LiquidTypesRmls = ActiveRML.LiquidTypesRmls; - foreach (var liquidTypeRml in LiquidTypesRmls) - { - CalibrationDataVM catVM = new CalibrationDataVM(liquidTypeRml.LiquidType); - - if (liquidTypeRml.DefaultCatData != null) + foreach (var liquidTypeRml in LiquidTypesRmls) { - catVM.CalibrationPoints = liquidTypeRml.GetCalibrationData().CalibrationPoints.Select(x => new CalibrationDataPointVM(x.X, x.Y)).ToObservableCollection(); + CalibrationDataVM catVM = new CalibrationDataVM(liquidTypeRml.LiquidType); + + if (liquidTypeRml.DefaultCatData != null) + { + catVM.CalibrationPoints = liquidTypeRml.GetCalibrationData().CalibrationPoints.Select(x => new CalibrationDataPointVM(x.X, x.Y)).ToObservableCollection(); + } + + CalibrationDataViewVM.LiquidsCalibrationData.Add(catVM); } - CalibrationDataViewVM.LiquidsCalibrationData.Add(catVM); - } + ColorConversionViewVM = new ColorConversionViewVM(_notification) + { + RML = ActiveRML, + CCT = SelectedCCT, + LiquidsCalibrationData = CalibrationDataViewVM.LiquidsCalibrationData, + LiquidTypesRmls = LiquidTypesRmls, + }; - ColorConversionViewVM = new ColorConversionViewVM(_notification) - { - RML = ActiveRML, - CCT = SelectedCCT, - LiquidsCalibrationData = CalibrationDataViewVM.LiquidsCalibrationData, - LiquidTypesRmls = LiquidTypesRmls, - }; + ColorCalibrationVM = new ColorCalibrationViewVM(_notification) + { + RML = ActiveRML, + LiquidTypes = LiquidTypesRmls.Where(x => x.LiquidType.HasPigment).ToList().Select(y => y.LiquidType).ToList(), + }; - View.NavigateTo(RmlNavigationView.RmlView); + _rmlBeforeSave = RmlDTO.FromObservable(ActiveRML); - InvalidateRelayCommands(); + View.NavigateTo(RmlNavigationView.RmlView); - IsFree = true; + InvalidateRelayCommands(); + + IsFree = true; + } + catch (Exception ex) + { + LogManager.Log($"Error loading RML '{ActiveRML.Name}'..."); + _notification.ShowError($"Error loading the selected thread.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } } } @@ -371,6 +485,7 @@ namespace Tango.MachineStudio.RML.ViewModels LinearMassDensityUnits = _active_context.LinearMassDensityUnits.ToObservableCollection(); FiberShapes = _active_context.FiberShapes.ToObservableCollection(); FiberSynths = _active_context.FiberSynths.ToObservableCollection(); + SpoolTypes = _active_context.SpoolTypes.ToObservableCollection(); } private async void AddNewRml() @@ -400,8 +515,10 @@ namespace Tango.MachineStudio.RML.ViewModels Rml rml = new Rml(); rml.Name = name; + 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(); @@ -423,6 +540,9 @@ namespace Tango.MachineStudio.RML.ViewModels _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]); _active_context.Rmls.Add(rml); await _active_context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, rml.Name, rml, "Rml created using Machine Studio."); + LoadActiveRML(rml.Guid); IsFree = true; @@ -432,25 +552,64 @@ namespace Tango.MachineStudio.RML.ViewModels private async void RemoveSelectedRml() { - if (_notification.ShowQuestion("Removing the selected RML will result in the loss of all related process parameters and default calibration data. Are you sure you want to delete the selected RML?")) + 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) + { + var vm = new RmlDeleteDialogViewVM(SelectedRML, Rmls.ToList(), rml_jobs.ToList()); + _notification.ShowModalDialog(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; } } @@ -468,15 +627,18 @@ namespace Tango.MachineStudio.RML.ViewModels using (var context = ObservablesContext.CreateDefault()) { - var rml = await new RmlBuilder(context).Set(SelectedRML.Guid).WithActiveParametersGroup().WithLiquidFactors().BuildAsync(); + var rml = await new RmlBuilder(context).Set(SelectedRML.Guid).WithActiveParametersGroup().WithLiquidFactors().WithSpools().BuildAsync(); Rml cloned = new Rml(); - rml.MapPrimitivesWithStrings(cloned); + rml.MapPropertiesTo(cloned, MappingFlags.NoReferenceTypes); cloned.Code = Rmls.Max(x => x.Code) + 1; cloned.Guid = Guid.NewGuid().ToString(); cloned.ID = 0; cloned.Name = name; + cloned.DisplayName = name; + cloned.RmlQualificationLevel = RmlQualifications.Provisional; + cloned.QualificationDate = DateTime.UtcNow; ProcessParametersTablesGroup group = new ProcessParametersTablesGroup(); group.Name = rml.GetActiveProcessGroup().Name; @@ -502,8 +664,19 @@ namespace Tango.MachineStudio.RML.ViewModels cloned.LiquidTypesRmls.Add(l); } + foreach (var spool in rml.RmlsSpools) + { + RmlsSpool s = new RmlsSpool(); + spool.MapPropertiesTo(s, MappingFlags.ValueTypesOnly); + s.RmlGuid = cloned.Guid; + s.SpoolTypeGuid = spool.SpoolTypeGuid; + cloned.RmlsSpools.Add(s); + } + context.Rmls.Add(cloned); await context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, cloned.Name, cloned, "RML cloned from Machine Studio."); } LoadRmls(); @@ -558,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?")) @@ -648,6 +826,11 @@ namespace Tango.MachineStudio.RML.ViewModels ActiveRML.LastUpdated = DateTime.UtcNow; + if (_rmlBeforeSave.QualificationLevel != ActiveRML.QualificationLevel) + { + ActiveRML.QualificationDate = DateTime.UtcNow; + } + if (SelectedCCT != null) { if (SelectedCCT.IsNew) @@ -665,18 +848,26 @@ namespace Tango.MachineStudio.RML.ViewModels } } + var rmlAfter = RmlDTO.FromObservable(ActiveRML); + await _active_context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlSaved, _authentication.CurrentUser, _rmlBeforeSave.Name, _rmlBeforeSave, rmlAfter, "RML saved using Machine Studio."); + + _rmlBeforeSave = rmlAfter; + + LoadActiveRML(ActiveRML.Guid); } } catch (Exception ex) { LogManager.Log(ex, $"Error saving RML {ActiveRML.Name}"); - _notification.ShowError($"An error occurred while trying to save the current RML.\n{ex.Message}"); + _notification.ShowError($"An error occurred while trying to save the current RML.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; } - - LoadActiveRML(ActiveRML.Guid); - - IsFree = true; } private void BackToRmls() @@ -692,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; @@ -804,6 +1001,8 @@ namespace Tango.MachineStudio.RML.ViewModels var rmlFile = await Rml.FromRmlFile(db, json); db.Rmls.Add(rmlFile); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlImported, _authentication.CurrentUser, rmlFile.Name, rmlFile, "RML imported from Machine Studio."); } await db.SaveChangesAsync(); @@ -860,5 +1059,26 @@ namespace Tango.MachineStudio.RML.ViewModels } #endregion + + #region Spools + + private void AddNewSpool() + { + _active_context.RmlsSpools.Add(new RmlsSpool() + { + Rml = ActiveRML, + }); + } + + private void RemoveSpool() + { + if (SelectedSpool != null) + { + _active_context.RmlsSpools.Remove(SelectedSpool); + ActiveRML.RmlsSpools.Remove(SelectedSpool); + } + } + + #endregion } } 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 _jobsToDelete; + + private List _jobsActions; + public List JobsActions + { + get { return _jobsActions; } + set { _jobsActions = value; RaisePropertyChangedAuto(); } + } + + public Rml Rml { get; set; } + + public List Rmls { get; set; } + + public List Actions { get; set; } + + public RmlDeleteDialogViewVM(Rml rml, List rmls, List jobsToDelete) + { + Rml = rml; + Rmls = rmls.Where(x => x.Guid != rml.Guid).ToList(); + _jobsToDelete = jobsToDelete; + JobsActions = new List(); + + Actions = new List() + { + RmlDeleteJobAction.Delete, + RmlDeleteJobAction.Change + }; + } + + public override void OnShow() + { + base.OnShow(); + + List list = new List(); + + 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 @@ + + + + + + + + + + + + Liquid Type: + + + + + + + + + + + + + + LIQUID FACTOR + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Factor: + + + + + + + Warning: + + + + + + + + + + + + + + + LINEARIZATION + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +{ + /// + /// Interaction logic for ColorCalibrationView.xaml + /// + 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/HeadCleaningParametersView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/HeadCleaningParametersView.xaml new file mode 100644 index 000000000..aec12aa63 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/HeadCleaningParametersView.xaml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + HEAD CLEANING PARAMETERS + + + + + + + + + + CLEANER + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/HeadCleaningParametersView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/HeadCleaningParametersView.xaml.cs new file mode 100644 index 000000000..8d036efa5 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/HeadCleaningParametersView.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 +{ + /// + /// Interaction logic for SpoolsView.xaml + /// + public partial class HeadCleaningParametersView : UserControl + { + public HeadCleaningParametersView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/MainView.xaml index ab5207722..e52ac4ece 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/MainView.xaml @@ -9,7 +9,7 @@ xmlns:local="clr-namespace:Tango.MachineStudio.RML.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}"> - + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ProcessParametersView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ProcessParametersView.xaml index b85fd2c12..03bf65522 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ProcessParametersView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/ProcessParametersView.xaml @@ -32,7 +32,7 @@ - ACTIVE PROCESS GROUP + ACTIVE PROCESS GROUP @@ -70,7 +70,7 @@ - + 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 @@ + + + + + + + + + + + + + + + DELETE + + + + + + + + + + + + + + + + + The following jobs must be removed or change thread type before the selected thread can be deleted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +{ + /// + /// Interaction logic for RmlDeleteDialogView.xaml + /// + 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 50f6a6297..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 @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:global="clr-namespace:Tango.MachineStudio.RML" + xmlns:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL" xmlns:observables="clr-namespace:Tango.BL.Entities;assembly=Tango.BL" xmlns:shapes="clr-namespace:Tango.SharedUI.Shapes;assembly=Tango.SharedUI" xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" @@ -19,6 +20,7 @@ + @@ -28,7 +30,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + PROPERTIES + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SITE RML + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml.cs new file mode 100644 index 000000000..03e9a2f75 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.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.Sites.Views +{ + /// + /// Interaction logic for SiteDetailsView.xaml + /// + public partial class SiteDetailsView : UserControl + { + public SiteDetailsView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml new file mode 100644 index 000000000..437003a8a --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml.cs new file mode 100644 index 000000000..e6a4a6fe6 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.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.Sites.Views +{ + /// + /// Interaction logic for SitesView.xaml + /// + public partial class SitesView : UserControl + { + public SitesView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config new file mode 100644 index 000000000..7b82e5f7c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config @@ -0,0 +1,85 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config new file mode 100644 index 000000000..e57143046 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/App.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/App.config index ed4582d5b..75b63289d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/App.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/App.config @@ -22,7 +22,7 @@ - + @@ -30,27 +30,27 @@ - + - + - + - + - + - + @@ -74,7 +74,7 @@ - + @@ -92,6 +92,10 @@ + + + + \ No newline at end of file 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 new file mode 100644 index 000000000..2d9a3cfd9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs @@ -0,0 +1,48 @@ +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 CollectionConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if(value != null && value is System.Collections.IEnumerable) + { + var colection = value as System.Collections.IEnumerable; + var text = new StringBuilder(); + foreach(var val in colection) + { + string visibleText = val.ToString(); + if(val is bool && parameter is string) + { + string[] tokens = (parameter as string).Split(','); + if(tokens.Count() > 1) + { + visibleText = (bool)val == true ? tokens[1] : tokens[0]; + } + } + text.Append(visibleText); + text.Append("/"); + } + string str_text = text.ToString(); + if(str_text.Length > 1) + { + str_text = str_text.Remove(str_text.Length - 1); + } + return str_text; + } + 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/DateTimeToStringFormatConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/DateTimeToStringFormatConverter.cs new file mode 100644 index 000000000..6b5154ce3 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/DateTimeToStringFormatConverter.cs @@ -0,0 +1,30 @@ +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 DateTimeToStringFormatConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value != null) + { + return ((TimeSpan)value).ToString(@"hh\:mm\:ss"); + } + else + { + return TimeSpan.FromSeconds(0).ToString(@"hh\:mm\:ss"); + } + } + + 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/JobLengthConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/JobLengthConverter.cs new file mode 100644 index 000000000..cd928d9c9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/JobLengthConverter.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 JobLengthConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + try + { + if (values != null && values.Count() == 3) + { + double length = (double)values[0]; + double endPoint = (double)values[1]; + double width = (double)values[2]; + var v = Math.Round((endPoint / length) * width, MidpointRounding.AwayFromZero); + + if (double.IsInfinity(v)) + { + return 0d; + } + return v; + } + } + catch { } + + return 0d; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} 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/LiquidTypeToColorConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidTypeToColorConverter.cs new file mode 100644 index 000000000..b36bf608e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidTypeToColorConverter.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; +using Tango.BL; +using Tango.BL.Enumerations; + +namespace Tango.MachineStudio.Statistics.Converters +{ + public class LiquidTypeToColorConverter : IValueConverter + { + private static Dictionary liquidTypes; + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (liquidTypes == null) + { + liquidTypes = new Dictionary(); + + foreach (var type in ObservablesStaticCollections.Instance.LiquidTypes.ToList()) + { + liquidTypes.Add(type.Type, type.LiquidTypeColor); + } + } + + if (value != null) + { + return liquidTypes[(LiquidTypes)value]; + } + + return value; + } + + 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/MidTankLevelToElementHeightConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/MidTankLevelToElementHeightConverter.cs new file mode 100644 index 000000000..de002046e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/MidTankLevelToElementHeightConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Globalization; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace Tango.MachineStudio.Statistics.Converters +{ + public class MidTankLevelToElementHeightConverter : IMultiValueConverter + { + public const double MAX_QUANTITY = 130000000; + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + try + { + double parentActualHeight; + Double.TryParse(values[0].ToString(), out parentActualHeight); + double quantity; + Double.TryParse(values[1].ToString(), out quantity); + + double midTankLevel = (double)Math.Min(quantity, MAX_QUANTITY); + double delta = ((midTankLevel / MAX_QUANTITY) * parentActualHeight); + if (quantity > 0 && midTankLevel < (MAX_QUANTITY/10))// if quantity < 10|% set 2 pixel + delta = 2.0; + var test = delta; + return parentActualHeight - delta; + } + catch + { + return 0d; + } + } + + public object[] ConvertBack(object value, Type[] targetTypes, 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 new file mode 100644 index 000000000..97f4ec066 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/NanoLiterToLiterFormatConverter.cs @@ -0,0 +1,36 @@ +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 NanoLiterToLiterFormatConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + var longValue = System.Convert.ToUInt64(value.ToString()); + double val = (longValue / 1000000000d); + if (parameter is string) + { + string format= (string)parameter; + return val.ToString(format); + } + return val.ToString(); + } + 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/StringToBoolYesNoNullConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToBoolYesNoNullConverter.cs new file mode 100644 index 000000000..f7633a7d0 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToBoolYesNoNullConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows.Data; + +namespace Tango.MachineStudio.Statistics.Converters +{ + public class StringToBoolYesNoNullConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if(value is bool) + { + return (bool)value ? "Yes" : "No"; + } + return "Null"; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + //throw new NotImplementedException(); + if (value is ComboBoxItem) + { + string str_val = ((ComboBoxItem)value).Content.ToString(); + if (str_val.ToUpper() == "NO") + return false; + if (str_val.ToUpper() == "YES") + return true; + } + return null; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToFirstLetterConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToFirstLetterConverter.cs new file mode 100644 index 000000000..a1c9561b9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToFirstLetterConverter.cs @@ -0,0 +1,30 @@ +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 StringToFirstLetterConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value != null && value.ToString().Length > 1) + { + return value.ToString().First().ToString(); + } + else + { + return value; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file 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/Models/JobRunModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs new file mode 100644 index 000000000..83897ca16 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; + +namespace Tango.MachineStudio.Statistics.Models +{ + public class JobRunModel + { + public JobRun JobRun { get; set; } + + public Machine Machine { get; set; } + + public User User { get; set; } + + public TimeSpan? UploadDuration { get; set; } + + public TimeSpan? HeatingDuration { get; set; } + + public RmlModel Rml { get; set; } + + public void Init() + { + if (JobRun.HeatingStartDate != null) + { + UploadDuration = JobRun.HeatingStartDate - JobRun.StartDate; + } + + if (JobRun.ActualStartDate != null && JobRun.HeatingStartDate != null) + { + HeatingDuration = JobRun.ActualStartDate - JobRun.HeatingStartDate; + } + + + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunStatisticsModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunStatisticsModel.cs new file mode 100644 index 000000000..98b719cae --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunStatisticsModel.cs @@ -0,0 +1,45 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; +using Tango.Core.ExtensionMethods; + +namespace Tango.MachineStudio.Statistics.Models +{ + public class JobRunStatisticsModel : JobRun + { + private static Dictionary _machines = new Dictionary(); + + public JobRunStatisticsModel() + { + + } + + public JobRunStatisticsModel(JobRun run) + { + run.MapPropertiesTo(this, MappingFlags.NoReferenceTypes); + } + + public Task LoadMachine(ObservablesContext context) + { + return Task.Factory.StartNew(() => + { + if (!_machines.ContainsKey(MachineGuid)) + { + Machine = context.Machines.SingleOrDefault(x => x.Guid == MachineGuid); + _machines.Add(MachineGuid, Machine); + } + else + { + Machine = _machines[MachineGuid]; + } + }); + } + + public Machine Machine { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/RmlModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/RmlModel.cs new file mode 100644 index 000000000..789779e42 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/RmlModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Statistics.Models +{ + public class RmlModel + { + public string Guid { get; set; } + + public string Name { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/StatisticsValueCollection.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/StatisticsValueCollection.cs new file mode 100644 index 000000000..b5615e4d1 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/StatisticsValueCollection.cs @@ -0,0 +1,319 @@ +using LiveCharts; +using LiveCharts.Wpf; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; +using Tango.BL.Enumerations; +using Tango.BL.ValueObjects; +using Tango.Core; +using System.Windows.Media; +using System.Windows; + +namespace Tango.MachineStudio.Statistics.Models +{ + public class StatisticsValue + { + public string Name { get; set; } + + public object Value { get; set; } + + public string Unit { get; set; } + } + public class MoreValue + { + public string Text { get; set; } + } + + public class StatisticsValueCollection : ExtendedObject + { + private List _pieColors; + + #region Properties + + private ObservableCollection _statisticsCollection; + + /// + /// Gets or sets the statistics collection of StatisticsValue object. + /// + public ObservableCollection StatisticsCollection + { + get { return _statisticsCollection; } + set + { + _statisticsCollection = value; + RaisePropertyChangedAuto(); + } + } + + private List _threadConsumptionPerThread; + /// + /// Gets or sets the thread consumption per thread list. + /// + public List ThreadConsumptionPerThread + { + get { return _threadConsumptionPerThread; } + set { _threadConsumptionPerThread = value; RaisePropertyChangedAuto(); } + } + + /// + /// Gets or sets the thread consumption per thread collection. + /// + public CompositeCollection ThreadConsumptionPerThreadCollection { get; set; } + + private LabeledSeriesCollection _pieJobSource; + + /// + /// Gets or sets the pie job source. + /// + public LabeledSeriesCollection PieJobSource + { + get { return _pieJobSource; } + set { _pieJobSource = value; RaisePropertyChangedAuto(); } + } + + private LabeledSeriesCollection _pieJobRunStatus; + + /// + /// Gets or sets the pie job run status. + /// + public LabeledSeriesCollection PieJobRunStatus + { + get { return _pieJobRunStatus; } + set { _pieJobRunStatus = value; RaisePropertyChangedAuto(); } + } + + private LabeledSeriesCollection _pieGradientSolid; + + /// + /// Gets or sets the pie gradient solid. + /// + public LabeledSeriesCollection PieGradientSolid + { + get { return _pieGradientSolid; } + set { _pieGradientSolid = value; RaisePropertyChangedAuto(); } + } + + private List _liquidQuantities; + + /// + /// Gets or sets the liquid quantities. + /// + public List LiquidQuantities + { + get + { + if (_liquidQuantities == null) + { + _liquidQuantities = new List(); + } + return _liquidQuantities; + } + set + { _liquidQuantities = value; RaisePropertyChangedAuto(); } + } + + private ulong _totalLiquidQuantities; + + /// + /// Gets or sets the total liquid quantities. + /// + public ulong TotalLiquidQuantities + { + get { return _totalLiquidQuantities; } + set { _totalLiquidQuantities = value; RaisePropertyChangedAuto(); } + } + + #endregion + + public StatisticsValueCollection() + { + StatisticsCollection = new ObservableCollection(); + ThreadConsumptionPerThread = new List(); + ThreadConsumptionPerThreadCollection = new CompositeCollection(); + + _pieColors = new List(); + _pieColors.Add(((SolidColorBrush)Application.Current.Resources["RedBrush500"]).Color); + _pieColors.Add(((SolidColorBrush)Application.Current.Resources["OrangeBrush"]).Color); + _pieColors.Add(((SolidColorBrush)Application.Current.Resources["GreenBrush"]).Color); + _pieColors.Add(((SolidColorBrush)Application.Current.Resources["BlueBrush100"]).Color); + _pieColors.Add(Color.FromRgb(255, 216, 76)); + + + PieJobSource = new LabeledSeriesCollection() + { + Title = "PPC/MS", + SeriesColors = _pieColors, + }; + PieJobRunStatus = new LabeledSeriesCollection() + { + Title = "Failed/Aborted/Completed", + SeriesColors = _pieColors, + }; + PieGradientSolid = new LabeledSeriesCollection() + { + Title = "Gradient/Solid", + SeriesColors = _pieColors, + }; + } + + /// + /// Cleans all values. + /// + public void Clean() + { + StatisticsCollection.Clear(); + ThreadConsumptionPerThreadCollection.Clear(); + ThreadConsumptionPerThread.Clear(); + PieJobSource.SeriesCollection.Clear(); + PieJobRunStatus.SeriesCollection.Clear(); + PieGradientSolid.SeriesCollection.Clear(); + } + + /// + /// Adds the statistics value. + /// + public void AddStatisticsValue(string name, object value, string unit) + { + StatisticsCollection.Add(new StatisticsValue() { Name = name, Value = value, Unit = unit }); + RaisePropertyChanged("StatisticsCollection"); + } + + /// + /// Creates the thread consumption per thread. + /// + public void CreateThreadConsumptionPerThread(List threads) + { + ThreadConsumptionPerThreadCollection.Add(new CollectionContainer() { Collection = threads.Take(threads.Count() > 2 ? 2 : threads.Count()) }); + if (threads.Count() > 2) + { + ThreadConsumptionPerThreadCollection.Add(new CollectionContainer() { Collection = new List() { new MoreValue() { Text = "More threads ..." } } }); + ThreadConsumptionPerThread = threads.Skip(2).ToList(); + } + + RaisePropertyChanged("ThreadConsumptionPerThreadCollection"); + } + + #region GeneratePieChart + Func labelPoint = chartPoint => + string.Format("{0} ({1:P})", chartPoint.Y, chartPoint.Participation); + + public void GeneratePieJobSource(int PPCCount, int MSCount) + { + var series = new PieSeries() + { + Title = "PPC", + Values = new ChartValues() { PPCCount }, + Fill = new SolidColorBrush(_pieColors[4]), + DataLabels = true, + ToolTip = "", + LabelPoint = labelPoint + + }; + + PieJobSource.SeriesCollection.Add(series); + + series = new PieSeries() + { + Title = "MS", + Values = new ChartValues() { MSCount }, + Fill = new SolidColorBrush(_pieColors[3]), + DataLabels = true, + ToolTip = "", + LabelPoint = labelPoint + }; + PieJobSource.SeriesCollection.Add(series); + RaisePropertyChanged("PieJobSource"); + } + + public void GeneratePieJobRunStatus(int failedCount, int abortedCount, int completedCount) + { + var series = new PieSeries() + { + Title = "Failed", + Values = new ChartValues() { failedCount }, + Fill = new SolidColorBrush(_pieColors[0]), + DataLabels = true, + ToolTip = "", + LabelPoint = labelPoint + }; + + PieJobRunStatus.SeriesCollection.Add(series); + + series = new PieSeries() + { + Title = "Aborted", + Values = new ChartValues() { abortedCount }, + Fill = new SolidColorBrush(_pieColors[1]), + DataLabels = true, + ToolTip = "", + LabelPoint = labelPoint, + + }; + PieJobRunStatus.SeriesCollection.Add(series); + + series = new PieSeries() + { + Title = "Completed", + Values = new ChartValues() { completedCount }, + Fill = new SolidColorBrush(_pieColors[2]), + DataLabels = true, + ToolTip = "", + LabelPoint = labelPoint + }; + PieJobRunStatus.SeriesCollection.Add(series); + + RaisePropertyChanged("PieJobRunStatus"); + } + + public void GeneratePieGradientSolid(int gradientCount, int solidCount) + { + var series = new PieSeries() + { + Title = "Solid", + Values = new ChartValues() { solidCount }, + Fill = new SolidColorBrush(_pieColors[4]), + DataLabels = true, + ToolTip = "", + LabelPoint = labelPoint + }; + PieGradientSolid.SeriesCollection.Add(series); + + series = new PieSeries() + { + Title = "Gradient", + Values = new ChartValues() { gradientCount }, + Fill = new SolidColorBrush(_pieColors[3]), + DataLabels = true, + ToolTip = "", + LabelPoint = labelPoint + + }; + + PieGradientSolid.SeriesCollection.Add(series); + + + RaisePropertyChanged("PieGradientSolid"); + } + #endregion + + /// + /// Generates the statistics liquid quantity and TotalLiquidQuantities. + /// + public void GenerateStatisticsLiquidQuantity(List liquidQuantities) + { + LiquidQuantities = liquidQuantities; + TotalLiquidQuantities = 0; + + foreach (var item in liquidQuantities) + { + TotalLiquidQuantities += (ulong)item.Quantity; + } + } + + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/TotalLiquidQuantityModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/TotalLiquidQuantityModel.cs new file mode 100644 index 000000000..b5e2e9fb7 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/TotalLiquidQuantityModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Enumerations; + +namespace Tango.MachineStudio.Statistics.Models +{ + public class TotalLiquidQuantityModel + { + public LiquidTypes LiquidType { get; set; } + public ulong Quantity { 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 243663c5a..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 @@ -38,6 +38,9 @@ ..\..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + ..\..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll + ..\..\..\packages\LiveCharts.0.9.7\lib\net45\LiveCharts.dll @@ -73,13 +76,38 @@ + + + + + + + + + + + + + + + + PieChartTooltipControl.xaml + + + + + ChartsView.xaml + + + JobRunsView.xaml + MainView.xaml @@ -94,6 +122,14 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -128,6 +164,10 @@ + + {bb2abb74-ba58-4812-83aa-ec8171f42df4} + Tango.AutoComplete + {f441feee-322a-4943-b566-110e12fd3b72} Tango.BL @@ -136,10 +176,18 @@ {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} Tango.Core + + {58e8825f-0c96-449c-b320-1e82b0aa876b} + Tango.CSV + {bc932dbd-7cdb-488c-99e4-f02cf441f55e} Tango.Logging + + {e4927038-348d-4295-aaf4-861c58cb3943} + Tango.PMR + {22f87980-e990-4686-be81-be63d562c4d5} Tango.Serialization 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"> - + 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 new file mode 100644 index 000000000..a98257086 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs @@ -0,0 +1,364 @@ +using LiveCharts; +using LiveCharts.Wpf; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Media; +using Tango.BL.Enumerations; +using Tango.MachineStudio.Common; +using Tango.MachineStudio.Statistics.Models; +using Tango.BL.Entities; +using Tango.SharedUI; +using Tango.BL; +using Tango.MachineStudio.Common.Notifications; +using System.Threading.Tasks; +using Tango.Core.Commands; + +namespace Tango.MachineStudio.Statistics.ViewModels +{ + public class ChartsViewVM : ViewModel + { + private INotificationProvider _notification; + //private ObservablesContext _context; + private List _job_runs; + private bool _loaded; + + #region Properties + private LabeledSeriesCollection _timelineJobStatusSeries; + public LabeledSeriesCollection TimelineJobStatusSeries + { + get { return _timelineJobStatusSeries; } + set { _timelineJobStatusSeries = value; RaisePropertyChangedAuto(); } + } + + private LabeledSeriesCollection _pieJobFailedReasons; + public LabeledSeriesCollection PieJobFailedReasons + { + get { return _pieJobFailedReasons; } + set { _pieJobFailedReasons = value; RaisePropertyChangedAuto(); } + } + + private LabeledSeriesCollection _printPerWeekSeries; + public LabeledSeriesCollection PrintPerWeekSeries + { + get { return _printPerWeekSeries; } + set { _printPerWeekSeries = value; RaisePropertyChangedAuto(); } + } + + private DateTime _startDate; + public DateTime StartDate + { + get { return _startDate; } + set { _startDate = value; RaisePropertyChangedAuto(); RaisePropertyChanged("EndDate"); } + } + + private DateTime _endDate; + public DateTime EndDate + { + get { return _endDate; } + set { _endDate = value; RaisePropertyChangedAuto(); RaisePropertyChanged("StartDate"); } + } + + public RelayCommand LoadJobRunsCommand { get; set; } + #endregion + + public ChartsViewVM(INotificationProvider notificationProvider) + { + _notification = notificationProvider; + StartDate = DateTime.Now.AddMonths(-1); + EndDate = DateTime.Now; + LoadJobRunsCommand = new RelayCommand(async () => await LoadJobRuns(), () => IsFree); + } + + #region Generate Charts + + private async Task LoadJobRuns() + { + using (_notification.PushTaskItem("Loading statistics...")) + { + try + { + IsFree = false; + + await Task.Factory.StartNew(() => + { + using (var db = ObservablesContext.CreateDefault()) + { + 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(); + } + } + }); + + InvokeUIOnIdle(() => + { + if (_loaded) + { + OnDateRangeChanged(); + } + }); + + _loaded = true; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading statistics."); + } + finally + { + IsFree = true; + } + } + } + + + private List GetJobRunsByDateRange(DateTime startDate, DateTime endTime, JobRunStatus? status = null) + { + return _job_runs.Where(x => x.StartDate.ToLocalTime() >= startDate && x.StartDate.ToLocalTime() <= endTime && (status == null || x.JobRunStatus == status)).ToList(); + } + + private List GetJobRunsByDate(DateTime date, JobRunStatus? status = null) + { + return _job_runs.Where(x => x.StartDate.ToLocalTime().Date == date.Date && (status == null || x.JobRunStatus == status)).ToList(); + } + + private IEnumerable CreateDates(DateTime start, DateTime end) + { + for (DateTime date = start.Date; date.Date <= end.Date; date = date.AddDays(1)) + { + yield return date; + } + } + + private void GenerateTimelineJobStatusChart() + { + TimelineJobStatusSeries = new LabeledSeriesCollection() + { + Title = "Job Runs Status", + ChartTitle = "Number Of Runs", + LabelsTitle = "Date", + SeriesColors = new List() + { + Colors.Green, + Colors.Orange, + Colors.Red, + }, + }; + + Series completed_job_runs = new ColumnSeries() + { + Title = "Completed", + Values = new ChartValues(), + Fill = Brushes.Green, + MinWidth = 1, + + }; + Series aborted_job_runs = new ColumnSeries() + { + Title = "Aborted", + Values = new ChartValues(), + Fill = Brushes.Orange, + MinWidth = 1, + }; + Series failed_job_runs = new ColumnSeries() + { + Title = "Failed", + Values = new ChartValues(), + Fill = Brushes.Red, + MinWidth = 1, + }; + + if (EndDate - StartDate > TimeSpan.FromDays(40)) + { + completed_job_runs = new LineSeries() + { + Title = "Completed", + Values = new ChartValues(), + Fill = new SolidColorBrush(Colors.Green) { Opacity = 0.5 }, + MinWidth = 1, + PointGeometry = null, + StrokeThickness = 0, + + }; + aborted_job_runs = new LineSeries() + { + Title = "Aborted", + Values = new ChartValues(), + Fill = new SolidColorBrush(Colors.Orange) { Opacity = 0.5 }, + MinWidth = 1, + PointGeometry = null, + StrokeThickness = 0, + }; + failed_job_runs = new LineSeries() + { + Title = "Failed", + Values = new ChartValues(), + Fill = new SolidColorBrush(Colors.Red) { Opacity = 0.5 }, + MinWidth = 1, + PointGeometry = null, + StrokeThickness = 0, + }; + } + + foreach (var date in CreateDates(StartDate, EndDate)) + { + completed_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Completed).Count()); + aborted_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Aborted).Count()); + failed_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Failed).Count()); + + TimelineJobStatusSeries.Labels.Add(date.ToShortDateString()); + } + + + + TimelineJobStatusSeries.SeriesCollection.Add(failed_job_runs); + TimelineJobStatusSeries.SeriesCollection.Add(aborted_job_runs); + TimelineJobStatusSeries.SeriesCollection.Add(completed_job_runs); + } + + private void GeneratePieFailedReasonsChart() + { + var groups = GetJobRunsByDateRange(StartDate, EndDate, JobRunStatus.Failed).GroupBy(x => x.FailedMessage).OrderBy(x => x.Count()); + + List colors = new List(); + + int max = groups.Count() > 0 ? groups.Max(x => x.Count()) : 0; + + for (int i = 0; i < groups.Count(); i++) + { + int count = groups.ElementAt(i).Count(); + double alpha = Math.Max(((double)(count) / max * 200), 20); + colors.Add(Color.FromArgb((byte)alpha, 200, 0, 0)); + } + + PieJobFailedReasons = new LabeledSeriesCollection() + { + Title = "Job Failure Reasons", + SeriesColors = colors, + }; + + int index = 0; + + foreach (var group in groups) + { + int count = group.Count(); + + var series = new PieSeries() + { + Title = group.First().FailedMessage, + Values = new ChartValues() { count }, + Fill = new SolidColorBrush(colors[index++]), + DataLabels = true, + ToolTip = group.First().FailedMessage, + }; + + PieJobFailedReasons.SeriesCollection.Add(series); + } + } + + private void GeneratePrintPerWeekChart() + { + List range_job_runs = GetJobRunsByDateRange(StartDate, EndDate); + + Dictionary> weeks_print_avg = new Dictionary>(); + + //Init machines weeks averages dictionary. + foreach (var machine in range_job_runs.Select(x => x.Machine).OrderBy(x => x.Name).DistinctBy(x => x.Guid)) + { + weeks_print_avg[machine] = new List(); + } + + //Create all available dates + List all_dates = range_job_runs.Select(x => x.StartDate).ToList(); + + //get first Sunday. + DateTime current_sunday = all_dates.FirstOrDefault(x => x.DayOfWeek == DayOfWeek.Sunday); + + if (current_sunday != null && all_dates.Count > 0) + { + //Iterate over each week starting from the earliest Sunday. + while (current_sunday <= all_dates.Last()) + { + var week_job_runs = range_job_runs.Where(x => x.EndPosition > 10 && x.StartDate >= current_sunday && x.StartDate <= current_sunday.AddDays(7)).ToList(); + + foreach (var machine_job_runs in week_job_runs.GroupBy(x => x.Machine)) + { + weeks_print_avg[machine_job_runs.Key].Add(machine_job_runs.Select(x => x.EndPosition).Average()); + } + + current_sunday = current_sunday.AddDays(8); + } + } + + Dictionary week_print_avg = new Dictionary(); + + //Init machines week average dictionary. + foreach (var machine in weeks_print_avg) + { + if (machine.Value.Count > 0) + { + week_print_avg[machine.Key] = machine.Value.Average(); + } + } + + //Init chart series + PrintPerWeekSeries = new LabeledSeriesCollection() + { + Title = "Average Printed Thread Per Week (m)", + ChartTitle = "Average Print Per Week (m)", + LabelsTitle = "Date", + SeriesColors = new List() + { + + }, + }; + + //Init series colors intensity by number of prints. + double max = week_print_avg.Count > 0 ? week_print_avg.Max(x => x.Value) : 0; + foreach (var machine in week_print_avg) + { + double a = (machine.Value / max); + PrintPerWeekSeries.SeriesColors.Add(Color.FromArgb((byte)(255d * (machine.Value / max)), 0, 200, 0)); + } + + //Init columns. + int index = 0; + + foreach (var machine in week_print_avg) + { + var series = new ColumnSeries() + { + Title = machine.Key.Name, + Values = new ChartValues() { (int)machine.Value }, + Fill = new SolidColorBrush(PrintPerWeekSeries.SeriesColors[index++]), + DataLabels = true, + ToolTip = machine.Key.SerialNumber, + }; + + PrintPerWeekSeries.SeriesCollection.Add(series); + } + } + + #endregion + + #region Filter by Date + public void OnDateRangeChanged() + { + if (_job_runs != null)// && _job_runs.Count > 0)// && _loaded) + { + GenerateTimelineJobStatusChart(); + GeneratePieFailedReasonsChart(); + GeneratePrintPerWeekChart(); + } + } + #endregion + + } +} 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 new file mode 100644 index 000000000..ae1592d8d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs @@ -0,0 +1,729 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data.Entity; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Builders; +using Tango.BL.Entities; +using Tango.BL.Enumerations; +using Tango.Core.Commands; +using Tango.MachineStudio.Common; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Statistics.Models; +using Tango.SharedUI; +using Tango.SharedUI.Components; +using Tango.AutoComplete.Editors; +using System.Windows.Media; +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; + private List _allMachines; + private List _allUsers; + private List _rmlsModels; + + + + #region Properties + + private ObservableCollection _jobRuns; + /// + /// Gets or sets the job runs. Contains filtered data of JobRunModel. + /// + public ObservableCollection JobRuns + { + get { return _jobRuns; } + set + { + _jobRuns = value; + RaisePropertyChangedAuto(); + } + } + + private JobRunModel _selectedJobRun = null; + /// + /// Gets or sets the JobRunModel. Binding to selected item of grid items. + /// + public JobRunModel SelectedJobRun + { + get { return _selectedJobRun; } + set + { + _selectedJobRun = value; + RaisePropertyChangedAuto(); + } + } + + private SelectedObjectCollection _selectedMachines; + /// + /// Gets or sets the selected machines. Contains all available machines and selected machines. Binding to ComboBox Machines. + /// + public SelectedObjectCollection SelectedMachines + { + get { return _selectedMachines; } + set + { + _selectedMachines = value; + RaisePropertyChangedAuto(); + } + } + + private DateTime _startSelectedDate; + /// + /// Gets or sets the start selected date. + /// + public DateTime StartSelectedDate + { + get { return _startSelectedDate; } + set { _startSelectedDate = value; + RaisePropertyChangedAuto(); + } + } + + private DateTime _endSelectedDate; + /// + /// Gets or sets the end selected date. + /// + public DateTime EndSelectedDate + { + get { return _endSelectedDate; } + set { _endSelectedDate = value; RaisePropertyChangedAuto(); } + } + + protected Double _lengthLowerValue; + /// + /// Gets or sets the length lower value of Range Slider + /// + public Double LengthLowerValue + { + get { return _lengthLowerValue; } + set + { + _lengthLowerValue = value; + RaisePropertyChangedAuto(); + } + } + + protected Double _lengthUpperValue; + /// + /// Gets or sets the length upper value of Range Slider. + /// + public Double LengthUpperValue + { + get { return _lengthUpperValue; } + set + { + _lengthUpperValue = value; + RaisePropertyChangedAuto(); + } + } + + private SelectedObjectCollection _jobRunSelectedSources; + /// + /// Gets or sets the job run selected sources. Binding to ComboBox "Source". + /// + public SelectedObjectCollection JobRunSelectedSources + { + get { return _jobRunSelectedSources; } + set { _jobRunSelectedSources = value; RaisePropertyChangedAuto(); } + } + + private SelectedObjectCollection _jobRunSelectedStatuses; + /// + /// Gets or sets the job run selected statuses. Binding to ComboBox "Status". + /// + public SelectedObjectCollection JobRunSelectedStatuses + { + get { return _jobRunSelectedStatuses; } + set { _jobRunSelectedStatuses = value; RaisePropertyChangedAuto(); } + } + + public SelectedObjectCollection _isGradientSelection; + /// + /// Gets or sets the is gradient selection. Binding to ComboBox "IsGradient". + /// + public SelectedObjectCollection IsGradientSelection + { + get { return _isGradientSelection; } + set + { + _isGradientSelection = value; + RaisePropertyChangedAuto(); + } + } + + private SelectedObjectCollection _selectedThreads; + /// + /// Gets or sets the selected threads. Contains all available threads and selected threads. Binding to ComboBox "Thread". + /// + public SelectedObjectCollection SelectedThreads + { + get { return _selectedThreads; } + set + { + _selectedThreads = value; + RaisePropertyChangedAuto(); + } + } + + private HeadCleaningSelectionEnum _headCleaningSelected; + + public HeadCleaningSelectionEnum HeadCleaningSelected + { + get { return _headCleaningSelected; } + set + { + _headCleaningSelected = value; + RaisePropertyChangedAuto(); + } + } + + + /// + /// Gets or sets the JobRuns providers. + /// + public ISuggestionProvider JobsProvider { get; set; } + + private Job _selectedJob; + /// + /// Gets or sets the job. + /// + public Job SelectedJob + { + get { return _selectedJob; } + set + { + _selectedJob = value; + RaisePropertyChangedAuto(); + } + } + + /// + /// Gets or sets the statistics value collection. Class - container included calculated statistic values. + /// + public StatisticsValueCollection StatisticsValueCollection { get; set; } + + #endregion + + public RelayCommand LoadJobRunsCommand { get; set; } + + public RelayCommand ExportToExcelCommand { get; set; } + + public JobRunsViewVM(INotificationProvider notificationProvider) + { + _notification = notificationProvider; + JobRuns = new ObservableCollection(); + LoadJobRunsCommand = new RelayCommand(async () => await LoadJobRuns(), () => IsFree); + ExportToExcelCommand = new RelayCommand(ExportToExcel, () => IsFree); + LengthUpperValue = 10000.0; + LengthLowerValue = 0.0; + DateTime now = DateTime.Now; + StartSelectedDate = now.AddMonths(-1); + EndSelectedDate = now; + + JobRunSelectedSources = new SelectedObjectCollection(new ObservableCollection() + { + JobSource.Local, + JobSource.Remote + }, new ObservableCollection() + { + JobSource.Local, + JobSource.Remote + }); + JobRunSelectedSources.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(JobRunSelectedSources)); + JobRunSelectedSources.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(JobRunSelectedSources)); + + JobRunSelectedStatuses = new SelectedObjectCollection(new ObservableCollection() + { + JobRunStatus.Aborted, + JobRunStatus.Completed, + JobRunStatus.Failed, + + }, new ObservableCollection() + { + JobRunStatus.Aborted, + JobRunStatus.Completed, + JobRunStatus.Failed, + + }); + JobRunSelectedStatuses.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(JobRunSelectedStatuses)); + JobRunSelectedStatuses.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(JobRunSelectedStatuses)); + + IsGradientSelection = new SelectedObjectCollection(new ObservableCollection + { + true, + false + }, new ObservableCollection + { + true, + false + }); + IsGradientSelection.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); + IsGradientSelection.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); + + HeadCleaningSelected = HeadCleaningSelectionEnum.Exclude; + + JobsProvider = new SuggestionProvider((filter) => + { + try + { + if (filter != null) + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + return db.Jobs.Where(x => x.Name != null && x.Name.ToLower().Contains(filter.ToLower())).ToList(); + } + } + else + { + return new List(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading jobs."); + return null; + } + }); + + StatisticsValueCollection = new StatisticsValueCollection(); + } + + /// + /// Initializes this instance. Called form main view VM in OnApplicationReady + /// + public async void Init() + { + using (_notification.PushTaskItem("Loading job runs...")) + { + try + { + IsFree = false; + + using (var db = ObservablesContext.CreateDefault()) + { + _allMachines = await db.Machines.ToListAsync(); + _allUsers = await db.Users.Include(x => x.Contact).ToListAsync(); + _rmlsModels = await db.Rmls.Select(x => new RmlModel() { Name = x.Name, Guid = x.Guid }).ToListAsync(); + SelectedMachines = new SelectedObjectCollection(_allMachines.ToObservableCollection(), new ObservableCollection()); + SelectedThreads = new SelectedObjectCollection(_rmlsModels.ToObservableCollection(), new ObservableCollection()); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading job runs."); + } + finally + { + IsFree = true; + } + } + + } + + /// + /// Loads the job runs by filters. + /// + private async Task LoadJobRuns() + { + using (_notification.PushTaskItem("Loading job runs...")) + { + try + { + IsFree = false; + + using (var db = ObservablesContext.CreateDefault()) + { + DateTime startUtc = new DateTime(StartSelectedDate.Year, StartSelectedDate.Month, StartSelectedDate.Day, 0, 0, 0).ToUniversalTime(); + TimeSpan offsetTime = (EndSelectedDate.Date == DateTime.Now.Date) ? DateTime.Now.TimeOfDay : new TimeSpan(23, 59, 59); + DateTime endUtc = EndSelectedDate.ToUniversalTime() + offsetTime; + + string jobName = SelectedJob == null ? "" : SelectedJob.Name; + + var db_JobRuns = db.JobRuns.Where(x => (x.StartDate <= endUtc && x.StartDate >= startUtc)) + .Select(x => new + { + x.ID, + x.ActualStartDate, + x.EndDate, + x.EndPosition, + x.GradientResolutionCm, + x.Guid, + x.HeatingStartDate, + x.IsGradient, + x.JobGuid, + x.JobLength, + x.JobName, + x.JobSource, + x.MachineGuid, + x.RmlGuid, + x.StartDate, + x.Status, + x.UploadingStartDate, + x.UserGuid, + x.CyanQuantity, + x.MagentaQuantity, + x.YellowQuantity, + x.BlackQuantity, + x.TransparentQuantity, + x.LubricantQuantity, + x.CleanerQuantity, + x.IsHeadCleaning + }); + var machineIDs = new HashSet(SelectedMachines.SynchedSource.ToList().Select(p => p.Guid)); + if (machineIDs.Count > 0) + { + db_JobRuns = db_JobRuns.Where(x => machineIDs.Contains(x.MachineGuid)); + } + int[] jobRunSourceArr = JobRunSelectedSources.SynchedSource.Select(x => (int)x).ToArray(); + if (jobRunSourceArr.Length > 0) + { + db_JobRuns = db_JobRuns.Where(x => jobRunSourceArr.Contains(x.JobSource)); + } + int[] jobRunStatusArr = JobRunSelectedStatuses.SynchedSource.Select(x => (int)x).ToArray(); + if (jobRunStatusArr.Length > 0) + { + db_JobRuns = db_JobRuns.Where(x => jobRunStatusArr.Contains(x.Status)); + } + bool[] isGradientArr = IsGradientSelection.SynchedSource.Select(x => (bool)x).ToArray(); + if (isGradientArr.Length > 0) + { + 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 rmlGuids = SelectedThreads.SynchedSource.Select(y => y.Guid).ToList(); + if (rmlGuids != null && rmlGuids.Count > 0) + { + db_JobRuns = db_JobRuns.Where(x => rmlGuids.Contains(x.RmlGuid)); + } + if (!String.IsNullOrEmpty(jobName)) + { + db_JobRuns = db_JobRuns.Where(x => x.JobName.ToLower().StartsWith(jobName.ToLower())); + } + + var runs_db = await db_JobRuns.ToListAsync(); //Execute actual query. + + + List runs = runs_db.Where(x => (x.JobLength < LengthUpperValue && x.JobLength >= LengthLowerValue)) + .Select(x => new JobRun() + { + ID = x.ID, + ActualStartDate = x.ActualStartDate, + EndDate = x.EndDate, + EndPosition = x.EndPosition, + GradientResolutionCm = x.GradientResolutionCm, + Guid = x.Guid, + HeatingStartDate = x.HeatingStartDate, + IsGradient = x.IsGradient, + JobGuid = x.JobGuid, + JobLength = x.JobLength, + JobName = x.JobName, + JobSource = x.JobSource, + MachineGuid = x.MachineGuid, + RmlGuid = x.RmlGuid, + StartDate = x.StartDate, + Status = x.Status, + UploadingStartDate = x.UploadingStartDate, + UserGuid = x.UserGuid, + CyanQuantity = x.CyanQuantity, + MagentaQuantity = x.MagentaQuantity, + YellowQuantity = x.YellowQuantity, + BlackQuantity = x.BlackQuantity, + TransparentQuantity = x.TransparentQuantity, + LubricantQuantity = x.LubricantQuantity, + CleanerQuantity = x.CleanerQuantity, + IsHeadCleaning = x.IsHeadCleaning + }).ToList(); + + var modelList = runs.Select(x => new JobRunModel() + { + JobRun = x, + Machine = _allMachines.FirstOrDefault(y => y.Guid == x.MachineGuid), + User = _allUsers.SingleOrDefault(y => y.Guid == x.UserGuid), + Rml = _rmlsModels.SingleOrDefault(y => y.Guid == x.RmlGuid), + }).OrderByDescending(x => x.JobRun.StartDate).ToList(); + + modelList.ForEach(x => x.Init()); + JobRuns = modelList.ToObservableCollection(); + GenerateStatistics(); + } + + + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading job runs."); + } + finally + { + IsFree = true; + } + } + } + + 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 csvFile = new CsvFile(new CsvDestination(dlg.FileName), new CsvDefinition() + { + Columns = new List() + { + "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); + + } + + 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 + + /// + /// Generates the statistics. + /// + protected void GenerateStatistics() + { + StatisticsValueCollection.Clean(); + if (JobRuns.Count() == 0) + return; + GenerateTotalRunsCount(); + GenerateTotalRunsLength(); + GenerateTotalThreadConsumption(); + GenerateRunsDuration(); + GenerateAverageUploadDuration(); + GenerateAverageHeatingDuration(); + + GeneratePieCharts(); + CreateThreadConsumptionPerThread(); + GenerateAllLiquidQuantities(); + } + + protected void GenerateTotalRunsCount() + {//Total Runs: + int val = JobRuns.Count(); + StatisticsValueCollection.AddStatisticsValue("Total Runs ", val, " "); + } + + /// + /// Generates the total length of the job runs. + /// + protected void GenerateTotalRunsLength() + { + double val = JobRuns.Where(z => z.JobRun.EndPosition > 0).Sum(x => x.JobRun.JobLength); + StatisticsValueCollection.AddStatisticsValue("Total Runs Length", val, " m"); + } + + /// + /// Generates the duration and average of the job runs. + /// + protected void GenerateRunsDuration() + { + var selection = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.JobRun.EndDate != null && z.JobRun.ActualStartDate != null); + double val = 0d; + double average = 0d; + if (selection != null && selection.Count() > 0) + { + val = selection.Sum(x => (x.JobRun.EndDate - x.JobRun.ActualStartDate).Value.TotalHours); + average = selection.Average(x => (x.JobRun.EndDate - x.JobRun.ActualStartDate).Value.TotalMilliseconds); + } + StatisticsValueCollection.AddStatisticsValue("Total Dyeing Time", val, " hours"); + StatisticsValueCollection.AddStatisticsValue("Average Dyeing Time", Math.Max(TimeSpan.FromMilliseconds(average).TotalHours, 0), " hours"); + } + + /// + /// Generates the average upload duration of the job runs. + /// + protected void GenerateAverageUploadDuration() + { + var average = (long)JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.UploadDuration != null).Average(x => x.UploadDuration.Value.TotalMilliseconds); + StatisticsValueCollection.AddStatisticsValue("Average Upload Duration", Math.Max(TimeSpan.FromMilliseconds(average).TotalMinutes, 0), " minutes"); + } + + /// + /// Generates the average duration heating of the job runs. + /// + protected void GenerateAverageHeatingDuration() + { + var average = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.HeatingDuration != null && z.HeatingDuration.Value.Ticks > 0).Average(x => x.HeatingDuration.Value.TotalMilliseconds); + StatisticsValueCollection.AddStatisticsValue("Average Heating Duration", Math.Max(TimeSpan.FromMilliseconds(average).TotalMinutes, 0), " minutes"); + } + + /// + /// Generates the total thread consumption by EndPosition. + /// + protected void GenerateTotalThreadConsumption() + { + double val = JobRuns.Where(z => z.JobRun.EndPosition > 0).Sum(x => x.JobRun.EndPosition); + StatisticsValueCollection.AddStatisticsValue("Total Dyeing Length", val, " m"); + } + + /// + /// Generates the pie charts in percentage: JobSource, JobRunStatus, Gradient. + /// + protected void GeneratePieCharts() + { + int PPCCount = JobRuns.Count(x => x.JobRun.Source == JobSource.Local); + int MSCount = JobRuns.Count(x => x.JobRun.Source == JobSource.Remote); + StatisticsValueCollection.GeneratePieJobSource(PPCCount, MSCount); + + int failedCount = JobRuns.Count(x => x.JobRun.JobRunStatus == JobRunStatus.Failed); + int abortedCount = JobRuns.Count(x => x.JobRun.JobRunStatus == JobRunStatus.Aborted); + int completedCount = JobRuns.Count(x => x.JobRun.JobRunStatus == JobRunStatus.Completed); + StatisticsValueCollection.GeneratePieJobRunStatus(failedCount, abortedCount, completedCount); + + int gradientCount = JobRuns.Count(x => x.JobRun.IsGradient == true); + int solidCount = JobRuns.Count(x => x.JobRun.IsGradient == false); + StatisticsValueCollection.GeneratePieGradientSolid(gradientCount, solidCount); + + } + + /// + /// Creates the thread consumption per thread. + /// + protected void CreateThreadConsumptionPerThread() + { + var temp = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.Rml != null).GroupBy(x => x.Rml.Name); + List result = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.Rml != null && !String.IsNullOrEmpty(z.Rml.Name)).GroupBy(x => x.Rml.Name).Select(y => new StatisticsValue { Name = y.Key, Value = y.Sum(x => x.JobRun.EndPosition), Unit = "m" }).ToList(); + StatisticsValueCollection.CreateThreadConsumptionPerThread(result); + } + + /// + /// Generates all liquid quantities. + /// + protected void GenerateAllLiquidQuantities() + { + var runs = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.JobRun.LiquidQuantitiesFast.Count > 0).ToList(); + + Dictionary total_quantities = new Dictionary(); + + foreach (LiquidTypes ltype in (LiquidTypes[])Enum.GetValues(typeof(LiquidTypes))) + { + total_quantities[ltype] = 0; + } + + foreach (var run in runs) + { + foreach (var lq in run.JobRun.LiquidQuantitiesFast) + { + if (lq.Quantity < 0) + { + Debug.WriteLine($"Warning: JobRun '{run.JobRun.ID}' contains an invalid value '{lq.Quantity}' for {lq.LiquidType} quantity."); + } + + total_quantities[lq.LiquidType] += Convert.ToUInt64(Math.Max(lq.Quantity, 0)); + } + } + + List allLiquidQuantities = total_quantities.Select(x => new TotalLiquidQuantityModel() + { + LiquidType = x.Key, + Quantity = x.Value + }).ToList(); + + + //foreach (LiquidTypes ltype in (LiquidTypes[])Enum.GetValues(typeof(LiquidTypes))) + //{ + // var liquidQuantityByTypeList = db_liquidQuantities.Select(x => x.FirstOrDefault(y => y.LiquidType == ltype)).Where(x => x != null); + // var count = liquidQuantityByTypeList != null ? liquidQuantityByTypeList.Sum(x => x.Quantity) : 0; + // JobRunLiquidQuantity lq = new JobRunLiquidQuantity() { LiquidType = ltype, Quantity = count }; + // allLiquidQuantities.Add(lq); + //} + StatisticsValueCollection.GenerateStatisticsLiquidQuantity(allLiquidQuantities); + } + #endregion + + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs index ef9561d0b..e7e2013c5 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs @@ -7,360 +7,49 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Media; using Tango.BL; -using Tango.BL.Entities; using Tango.BL.Enumerations; using Tango.Core.Helpers; using Tango.MachineStudio.Common; using Tango.MachineStudio.Statistics.Models; using System.Data.Entity; using Tango.MachineStudio.Common.Notifications; +using Tango.BL.Entities; namespace Tango.MachineStudio.Statistics.ViewModels { public class MainViewVM : StudioViewModel { - private ObservablesContext _context; - private List _job_runs; - private bool rendered; private INotificationProvider _notification; - private bool _loaded; - - private LabeledSeriesCollection _timelineJobStatusSeries; - public LabeledSeriesCollection TimelineJobStatusSeries - { - get { return _timelineJobStatusSeries; } - set { _timelineJobStatusSeries = value; RaisePropertyChangedAuto(); } - } - - private LabeledSeriesCollection _pieJobFailedReasons; - public LabeledSeriesCollection PieJobFailedReasons - { - get { return _pieJobFailedReasons; } - set { _pieJobFailedReasons = value; RaisePropertyChangedAuto(); } - } - - private LabeledSeriesCollection _printPerWeekSeries; - public LabeledSeriesCollection PrintPerWeekSeries - { - get { return _printPerWeekSeries; } - set { _printPerWeekSeries = value; RaisePropertyChangedAuto(); } - } - private DateTime _startDate; - public DateTime StartDate + private ChartsViewVM _chartsViewVM; + public ChartsViewVM ChartsViewVM { - get { return _startDate; } - set { _startDate = value; RaisePropertyChangedAuto(); OnDateRangeChanged(); } + get { return _chartsViewVM; } + set { _chartsViewVM = value; RaisePropertyChangedAuto(); } } - private DateTime _endDate; - public DateTime EndDate + private JobRunsViewVM _jobRunsViewVM; + public JobRunsViewVM JobRunsViewVM { - get { return _endDate; } - set { _endDate = value; RaisePropertyChangedAuto(); OnDateRangeChanged(); } + get { return _jobRunsViewVM; } + set { _jobRunsViewVM = value; RaisePropertyChangedAuto(); } } - - 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 MainViewVM(INotificationProvider notificationProvider) { _notification = notificationProvider; - - StartDate = DateTime.Now.AddMonths(-1); - EndDate = DateTime.Now; + ChartsViewVM = new ChartsViewVM(_notification); + JobRunsViewVM = new JobRunsViewVM(_notification); } public override void OnApplicationReady() { - + JobRunsViewVM.Init(); } - private List GetJobRunsByDateRange(DateTime startDate, DateTime endTime, JobRunStatus? status = null) - { - return _job_runs.Where(x => x.StartDate.ToLocalTime() >= startDate && x.StartDate.ToLocalTime() <= endTime && (status == null || x.JobRunStatus == status)).ToList(); - } - - private List GetJobRunsByDate(DateTime date, JobRunStatus? status = null) - { - return _job_runs.Where(x => x.StartDate.ToLocalTime().Date == date.Date && (status == null || x.JobRunStatus == status)).ToList(); - } - - private IEnumerable CreateDates(DateTime start, DateTime end) - { - for (DateTime date = start.Date; date.Date <= end.Date; date = date.AddDays(1)) - { - yield return date; - } - } - - - - public override async void OnNavigatedTo() + public override void OnNavigatedTo() { base.OnNavigatedTo(); - - if (rendered) return; - - rendered = true; - - - using (_notification.PushTaskItem("Loading statistics...")) - { - IsFree = false; - - await Task.Factory.StartNew(() => - { - _context = ObservablesContext.CreateDefault(); - _job_runs = _context.JobRuns.Include(x => x.Job).Include(x => x.Job.Machine).OrderBy(x => x.StartDate).ToList(); - }); - - if (_job_runs.Count > 0) - { - MinDate = _job_runs.Min(x => x.StartDate); - MaxDate = _job_runs.Max(x => x.StartDate); - } - - InvokeUIOnIdle(() => - { - OnDateRangeChanged(); - }); - - _loaded = true; - - IsFree = true; - } - } - - private void OnDateRangeChanged() - { - if (_job_runs != null && _job_runs.Count > 0 && _loaded) - { - GenerateTimelineJobStatusChart(); - GeneratePieFailedReasonsChart(); - GeneratePrintPerWeekChart(); - } - } - - private void GenerateTimelineJobStatusChart() - { - TimelineJobStatusSeries = new LabeledSeriesCollection() - { - Title = "Job Runs Status", - ChartTitle = "Number Of Runs", - LabelsTitle = "Date", - SeriesColors = new List() - { - Colors.Green, - Colors.Orange, - Colors.Red, - }, - }; - - Series completed_job_runs = new ColumnSeries() - { - Title = "Completed", - Values = new ChartValues(), - Fill = Brushes.Green, - MinWidth = 1, - - }; - Series aborted_job_runs = new ColumnSeries() - { - Title = "Aborted", - Values = new ChartValues(), - Fill = Brushes.Orange, - MinWidth = 1, - }; - Series failed_job_runs = new ColumnSeries() - { - Title = "Failed", - Values = new ChartValues(), - Fill = Brushes.Red, - MinWidth = 1, - }; - - if (EndDate - StartDate > TimeSpan.FromDays(40)) - { - completed_job_runs = new LineSeries() - { - Title = "Completed", - Values = new ChartValues(), - Fill = new SolidColorBrush(Colors.Green) { Opacity = 0.5 }, - MinWidth = 1, - PointGeometry = null, - StrokeThickness = 0, - - }; - aborted_job_runs = new LineSeries() - { - Title = "Aborted", - Values = new ChartValues(), - Fill = new SolidColorBrush(Colors.Orange) { Opacity = 0.5 }, - MinWidth = 1, - PointGeometry = null, - StrokeThickness = 0, - }; - failed_job_runs = new LineSeries() - { - Title = "Failed", - Values = new ChartValues(), - Fill = new SolidColorBrush(Colors.Red) { Opacity = 0.5 }, - MinWidth = 1, - PointGeometry = null, - StrokeThickness = 0, - }; - } - - foreach (var date in CreateDates(StartDate, EndDate)) - { - completed_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Completed).Count()); - aborted_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Aborted).Count()); - failed_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Failed).Count()); - - TimelineJobStatusSeries.Labels.Add(date.ToShortDateString()); - } - - - - TimelineJobStatusSeries.SeriesCollection.Add(failed_job_runs); - TimelineJobStatusSeries.SeriesCollection.Add(aborted_job_runs); - TimelineJobStatusSeries.SeriesCollection.Add(completed_job_runs); - } - - private void GeneratePieFailedReasonsChart() - { - var groups = GetJobRunsByDateRange(StartDate, EndDate, JobRunStatus.Failed).GroupBy(x => x.FailedMessage).OrderBy(x => x.Count()); - - List colors = new List(); - - int max = groups.Count() > 0 ? groups.Max(x => x.Count()) : 0; - - for (int i = 0; i < groups.Count(); i++) - { - int count = groups.ElementAt(i).Count(); - double alpha = Math.Max(((double)(count) / max * 200), 20); - colors.Add(Color.FromArgb((byte)alpha, 200, 0, 0)); - } - - PieJobFailedReasons = new LabeledSeriesCollection() - { - Title = "Job Failure Reasons", - SeriesColors = colors, - }; - - int index = 0; - - foreach (var group in groups) - { - int count = group.Count(); - - var series = new PieSeries() - { - Title = group.First().FailedMessage, - Values = new ChartValues() { count }, - Fill = new SolidColorBrush(colors[index++]), - DataLabels = true, - ToolTip = group.First().FailedMessage, - }; - - PieJobFailedReasons.SeriesCollection.Add(series); - } - } - - private void GeneratePrintPerWeekChart() - { - List range_job_runs = GetJobRunsByDateRange(StartDate, EndDate); - - Dictionary> weeks_print_avg = new Dictionary>(); - - //Init machines weeks averages dictionary. - foreach (var machine in range_job_runs.Select(x => x.Job.Machine).OrderBy(x => x.Name).DistinctBy(x => x.Guid)) - { - weeks_print_avg[machine] = new List(); - } - - //Create all available dates - List all_dates = range_job_runs.Select(x => x.StartDate).ToList(); - - //get first Sunday. - DateTime current_sunday = all_dates.FirstOrDefault(x => x.DayOfWeek == DayOfWeek.Sunday); - - if (current_sunday != null && all_dates.Count > 0) - { - //Iterate over each week starting from the earliest Sunday. - while (current_sunday <= all_dates.Last()) - { - var week_job_runs = range_job_runs.Where(x => x.EndPosition > 10 && x.StartDate >= current_sunday && x.StartDate <= current_sunday.AddDays(7)).ToList(); - - foreach (var machine_job_runs in week_job_runs.GroupBy(x => x.Job.Machine)) - { - weeks_print_avg[machine_job_runs.Key].Add(machine_job_runs.Select(x => x.EndPosition).Average()); - } - - current_sunday = current_sunday.AddDays(8); - } - } - - Dictionary week_print_avg = new Dictionary(); - - //Init machines week average dictionary. - foreach (var machine in weeks_print_avg) - { - if (machine.Value.Count > 0) - { - week_print_avg[machine.Key] = machine.Value.Average(); - } - } - - //Init chart series - PrintPerWeekSeries = new LabeledSeriesCollection() - { - Title = "Average Printed Thread Per Week (m)", - ChartTitle = "Average Print Per Week (m)", - LabelsTitle = "Date", - SeriesColors = new List() - { - - }, - }; - - //Init series colors intensity by number of prints. - double max = week_print_avg.Count > 0 ? week_print_avg.Max(x => x.Value) : 0; - foreach (var machine in week_print_avg) - { - double a = (machine.Value / max); - PrintPerWeekSeries.SeriesColors.Add(Color.FromArgb((byte)(255d * (machine.Value / max)), 0, 200, 0)); - } - - //Init columns. - int index = 0; - - foreach (var machine in week_print_avg) - { - var series = new ColumnSeries() - { - Title = machine.Key.Name, - Values = new ChartValues() { (int)machine.Value }, - Fill = new SolidColorBrush(PrintPerWeekSeries.SeriesColors[index++]), - DataLabels = true, - ToolTip = machine.Key.SerialNumber, - }; - - PrintPerWeekSeries.SeriesCollection.Add(series); - } } } } 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 new file mode 100644 index 000000000..b76154941 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml @@ -0,0 +1,145 @@ + + + + + + + + + + + Start Date: + + + + + + + + + + + + + End Date: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 000000000..bd97ed2bc --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs @@ -0,0 +1,74 @@ +using LiveCharts; +using LiveCharts.Wpf; +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.Statistics.Views +{ + /// + /// Interaction logic for ChartsView.xaml + /// + public partial class ChartsView : UserControl + { + public ChartsView() + { + InitializeComponent(); + } + private void PieChart_DataHover(object sender, ChartPoint chartPoint) + { + 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 new file mode 100644 index 000000000..bc99c1bfa --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml @@ -0,0 +1,787 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Start Date: + + + + + + + + + + + + End Date: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 000000000..961d7f691 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs @@ -0,0 +1,175 @@ +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; +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.SharedUI.Components; + +namespace Tango.MachineStudio.Statistics.Views +{ + /// + /// Interaction logic for JobRunsView.xaml + /// + public partial class JobRunsView : UserControl + { + private int _lastSelectedGridItemIndex; + public JobRunsView() + { + InitializeComponent(); + _lastSelectedGridItemIndex = -1; + } + + + private void Button_Click(object sender, RoutedEventArgs e) + { + selectMachineButton.IsChecked = true; + e.Handled = true; + } + + private void JobRunSourcesButton_Click(object sender, RoutedEventArgs e) + { + selectJobRunSources.IsChecked = true; + e.Handled = true; + } + private void IsGradientButton_Click(object sender, RoutedEventArgs e) + { + selectIsGradient.IsChecked = true; + e.Handled = true; + } + private void JobRunStatusButton_Click(object sender, RoutedEventArgs e) + { + selectJobRunStatus.IsChecked = true; + e.Handled = true; + } + + private async void TextBox_GotFocus(object sender, RoutedEventArgs e) + { + await Task.Delay(200); + TextBox txtBox = sender as TextBox; + txtBox.SelectAll(); + } + + private void TextBox_PreviewMouseUp(object sender, MouseButtonEventArgs e) + { + e.Handled = true; + } + + private void SelectMachineButton_Click(object sender, RoutedEventArgs e) + { + selectThreadsButton.IsChecked = true; + 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; + _lastSelectedGridItemIndex = -1; + if (e.AddedItems != null && e.AddedItems.Count > 0) + { + DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(e.AddedItems[0]); + if (row != null) + { + _lastSelectedGridItemIndex = row.GetIndex(); + } + } + } + + 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.Statistics/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/MainView.xaml index 55804c7b3..21c099db9 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/MainView.xaml @@ -11,100 +11,28 @@ xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" 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}"> - + - - + + - - - - Start Date: - - - - - End Date: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/MainView.xaml.cs index 3948c4e5a..f0d1c39a7 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/MainView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/MainView.xaml.cs @@ -28,10 +28,6 @@ namespace Tango.MachineStudio.Statistics.Views InitializeComponent(); } - private void PieChart_DataHover(object sender, ChartPoint chartPoint) - { - var tooltip = ((chartPoint.ChartView as PieChart).DataTooltip as Tooltips.PieChartTooltipControl).Title; - txtPieTitle.Text = tooltip; - } + } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/packages.config index 31c5f029f..6938c8a4b 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/packages.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/packages.config @@ -1,6 +1,7 @@  + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage_yjpbed13_wpftmp.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage_yjpbed13_wpftmp.csproj new file mode 100644 index 000000000..698c6fe82 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Storage/Tango.MachineStudio.Storage_yjpbed13_wpftmp.csproj @@ -0,0 +1,154 @@ + + + + + Debug + AnyCPU + {5991F6B5-EA4E-41E9-A4F6-7D3A50010FD6} + library + Tango.MachineStudio.Storage + Tango.MachineStudio.Storage + v4.6.1 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + + + true + full + false + ..\..\..\Build\Machine Studio\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\..\..\Build\Machine Studio\Release\ + TRACE + prompt + 4 + + + + + + GlobalVersionInfo.cs + + + + + + + + + + MainView.xaml + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + {f441feee-322a-4943-b566-110e12fd3b72} + Tango.BL + + + {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} + Tango.Core + + + {4206ac58-3b57-4699-8835-90bf6db01a61} + Tango.Integration + + + {bc932dbd-7cdb-488c-99e4-f02cf441f55e} + Tango.Logging + + + {8491d07b-c1f6-4b62-a412-41b9fd2d6538} + Tango.SharedUI + + + {74e700b0-1156-4126-be40-ee450d3c3026} + Tango.Transport + + + {43135fb9-41db-4f87-9771-cf2c762027c0} + Tango.FirmwarePackageGenerator + + + {cb0b0aa2-bb24-4bca-a720-45e397684e12} + Tango.MachineStudio.Common + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Editors/BlowerElementEditor.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Editors/BlowerElementEditor.xaml index 524dd79c5..dae945940 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Editors/BlowerElementEditor.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/Editors/BlowerElementEditor.xaml @@ -56,8 +56,8 @@ - - + + @@ -80,7 +80,7 @@ - + @@ -90,7 +90,7 @@ + + + + + + + + + + + + EMAIL + + FIRST NAME + + LAST NAME + + + + + Provide this password to the user + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.xaml.cs new file mode 100644 index 000000000..cfa389ed1 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserCreationDialog.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.UsersAndRoles.Views +{ + /// + /// Interaction logic for UserCreationDialog.xaml + /// + public partial class UserCreationDialog : UserControl + { + public UserCreationDialog() + { + InitializeComponent(); + } + } +} 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 bb003f525..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,11 +14,15 @@ 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}"> + + + @@ -48,7 +52,7 @@ LOGIN - + @@ -74,12 +78,18 @@ - + @@ -95,7 +105,7 @@ - + @@ -167,7 +177,7 @@ - + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml index 0858d7e08..37f649a7a 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserView.xaml @@ -16,8 +16,6 @@ - - diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config index fe4f26e87..8696cb880 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/packages.config @@ -7,4 +7,5 @@ + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs index 74969fd27..2929ea405 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Authentication/IAuthenticationProvider.cs @@ -29,7 +29,7 @@ namespace Tango.MachineStudio.Common.Authentication /// The email. /// The password. /// - AuthenticationLoginResult Login(String email, String password, bool bypassVersionCheck = false); + AuthenticationLoginResult Login(String email, String password, LoginMethod method, bool bypassVersionCheck = false, Action logAction = null); /// /// Logs-out the current logged-in user. diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs index 11d156292..89b8920d9 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs @@ -18,6 +18,7 @@ using Tango.MachineStudio.Common.StudioApplication; using Tango.PMR.Diagnostics; using Tango.Integration.Operation; using Tango.Core.ExtensionMethods; +using Tango.Transport; namespace Tango.MachineStudio.Common.EventLogging { @@ -28,6 +29,7 @@ namespace Tango.MachineStudio.Common.EventLogging public class DefaultEventLogger : ExtendedObject, IEventLogger { private ObservablesContext _db; + private static object _lockInit = new object(); private Thread _logThread; private ConcurrentQueue _events; private IStudioApplicationManager _application; @@ -46,6 +48,15 @@ namespace Tango.MachineStudio.Common.EventLogging #endregion + #region Properties + + /// + /// Gets or sets a value indicating whether to save the incoming events to database. + /// + public bool SaveToDB { get; set; } + + #endregion + #region Constructors /// @@ -57,6 +68,8 @@ namespace Tango.MachineStudio.Common.EventLogging { _hostName = Environment.MachineName; + SaveToDB = true; + _events = new ConcurrentQueue(); _pendingEvents = new List(); @@ -77,24 +90,27 @@ namespace Tango.MachineStudio.Common.EventLogging private void Init() { - if (!_isInitialized) + lock (_lockInit) { - try + if (!_isInitialized) { - _db = ObservablesContext.CreateDefault(); + try + { + _db = ObservablesContext.CreateDefault(); + + _db.EventTypes.ToList(); - _db.EventTypes.ToList(); + foreach (var type in _db.EventTypes) + { + _eventTypesGuids.Add((EventTypes)type.Code, type); + } - foreach (var type in _db.EventTypes) + _isInitialized = true; + } + catch { - _eventTypesGuids.Add((EventTypes)type.Code, type); + _isInitialized = false; } - - _isInitialized = true; - } - catch - { - _isInitialized = false; } } } @@ -127,6 +143,8 @@ namespace Tango.MachineStudio.Common.EventLogging machine.RequestSent += Machine_RequestSent; machine.RequestFailed += Machine_RequestFailed; machine.ResponseReceived += Machine_ResponseReceived; + + SaveToDB = !(machine is IExternalBridgeSecureClient); } } @@ -137,7 +155,7 @@ namespace Tango.MachineStudio.Common.EventLogging /// The message. private void Machine_RequestSent(object sender, IMessage message) { - Log(EventTypes.REQUEST_SENT, String.Format("Sending request '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); + //Log(EventTypes.REQUEST_SENT, String.Format("Sending request '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); } /// @@ -147,7 +165,7 @@ namespace Tango.MachineStudio.Common.EventLogging /// The instance containing the event data. private void Machine_RequestFailed(object sender, RequestFailedEventArgs e) { - Log(EventTypes.REQUEST_FAILED, String.Format("Request failed '{0}'...{1}{2}{1}{3}", e.Message.GetType().Name, Environment.NewLine, e.Message.ToJsonString(), e.Exception.ToString())); + //Log(EventTypes.REQUEST_FAILED, String.Format("Request failed '{0}'...{1}{2}{1}{3}", e.Message.GetType().Name, Environment.NewLine, e.Message.ToJsonString(), e.Exception.ToString())); } /// @@ -157,7 +175,7 @@ namespace Tango.MachineStudio.Common.EventLogging /// The message. private void Machine_ResponseReceived(object sender, IMessage message) { - Log(EventTypes.RESPONSE_RECEIVED, String.Format("Response received '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); + //Log(EventTypes.RESPONSE_RECEIVED, String.Format("Response received '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString())); } /// @@ -180,10 +198,10 @@ namespace Tango.MachineStudio.Common.EventLogging /// The events. private void MachineEventsStateProvider_EventsResolved(object sender, IEnumerable events) { - foreach (var ev in events) - { - Log(String.Format("Event '{0}' resolved.", ev.EventType.Name)); - } + //foreach (var ev in events) + //{ + // Log(String.Format("Event '{0}' resolved.", ev.EventType.Name)); + //} } #endregion @@ -196,6 +214,8 @@ namespace Tango.MachineStudio.Common.EventLogging /// The machine event. public void Log(MachinesEvent machineEvent) { + Init(); + machineEvent.HostName = _hostName; machineEvent.EventType = _eventTypesGuids[machineEvent.Type]; @@ -243,7 +263,7 @@ namespace Tango.MachineStudio.Common.EventLogging machineEvent.EventType = _eventTypesGuids[eventType]; machineEvent.EventTypeGuid = machineEvent.EventType.Guid; - if (write_to_db) + if (write_to_db && SaveToDB) { Log(machineEvent); } @@ -307,6 +327,11 @@ namespace Tango.MachineStudio.Common.EventLogging /// public void FlushAll() { + if (!SaveToDB) + { + return; + } + bool _saveChanges = false; while (_events.Count > 0) diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/IEventLogger.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/IEventLogger.cs index ceb399d24..44916ec21 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/IEventLogger.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/IEventLogger.cs @@ -19,6 +19,11 @@ namespace Tango.MachineStudio.Common.EventLogging /// event EventHandler NewLog; + /// + /// Gets or sets a value indicating whether to save the incoming events to database. + /// + bool SaveToDB { get; set; } + /// /// Logs the specified machine event. /// diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Black.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Black.otf new file mode 100644 index 000000000..0341d05db Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Black.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-BlackIt.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-BlackIt.otf new file mode 100644 index 000000000..e0823abdf Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-BlackIt.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Bold.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Bold.otf new file mode 100644 index 000000000..2b9144e5c Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Bold.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-BoldIt.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-BoldIt.otf new file mode 100644 index 000000000..f21ed044d Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-BoldIt.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Demi.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Demi.otf new file mode 100644 index 000000000..ada716012 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Demi.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-DemiIt.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-DemiIt.otf new file mode 100644 index 000000000..ab9a133a5 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-DemiIt.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Heavy.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Heavy.otf new file mode 100644 index 000000000..b3630c982 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Heavy.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-HeavyIt.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-HeavyIt.otf new file mode 100644 index 000000000..e47f75546 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-HeavyIt.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-It.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-It.otf new file mode 100644 index 000000000..6f9b5fa49 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-It.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Light.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Light.otf new file mode 100644 index 000000000..27af39094 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Light.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-LightIt.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-LightIt.otf new file mode 100644 index 000000000..89085eeca Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-LightIt.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Medium.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Medium.otf new file mode 100644 index 000000000..04b2a8853 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Medium.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-MediumIt.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-MediumIt.otf new file mode 100644 index 000000000..91996979e Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-MediumIt.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Regular.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Regular.otf new file mode 100644 index 000000000..2703ba3f3 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Regular.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Thin.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Thin.otf new file mode 100644 index 000000000..666c69931 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-Thin.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-ThinIt.otf b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-ThinIt.otf new file mode 100644 index 000000000..b039daffe Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Fonts/Flexo-ThinIt.otf differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Images/machine_new.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Images/machine_new.png new file mode 100644 index 000000000..116e1e9c7 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Images/machine_new.png differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Images/machine_new_small.png b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Images/machine_new_small.png new file mode 100644 index 000000000..378879ce1 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Images/machine_new_small.png differ diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/MachineStudioSettings.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/MachineStudioSettings.cs index c307a8e33..25dfc2dc8 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/MachineStudioSettings.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/MachineStudioSettings.cs @@ -8,8 +8,10 @@ using System.Windows; using Tango.BL; using Tango.Integration.Operation; using Tango.Logging; +using Tango.MachineStudio.Common.Web; using Tango.PMR.Printing; using Tango.Settings; +using Tango.Transport.Adapters; using Tango.Web; namespace Tango.MachineStudio.Common @@ -39,6 +41,11 @@ namespace Tango.MachineStudio.Common /// public String LastLoginPassword { get; set; } + /// + /// Gets or sets the last login method. + /// + public LoginMethod LastLoginMethod { get; set; } + /// /// Gets or sets a value indicating whether to save the user credentials. /// @@ -49,11 +56,6 @@ namespace Tango.MachineStudio.Common /// public String LastVirtualMachineSerialNumber { get; set; } - /// - /// Gets or sets the logging categories. - /// - public List LoggingCategories { get; set; } - /// /// Gets or sets the last bounds. /// @@ -134,6 +136,26 @@ namespace Tango.MachineStudio.Common /// public TimeSpan ExternalBridgeRequestTimeout { get; set; } + /// + /// Gets or sets the external bridge continuous request timeout. + /// + public TimeSpan ExternalBridgeContinuousRequestTimeout { get; set; } + + /// + /// Gets or sets the external bridge SignalR hub. + /// + public String ExternalBridgeSignalRHub { get; set; } + + /// + /// Gets or sets a value indicating whether to enable external bridge scanning via SignalR. + /// + public bool EnableExternalBridgeSignalR { get; set; } + + /// + /// Gets or sets the TCP transport adapter write mode. + /// + public TcpTransportAdapterWriteMode TcpTransportAdapterWriteMode { get; set; } + /// /// Gets the machine service address. /// @@ -162,7 +184,6 @@ namespace Tango.MachineStudio.Common public MachineStudioSettings() { LastBounds = new Rect(); - LoggingCategories = new List(); DefaultIssueReportTags = new List(); StudioModulesBounds = new List(); Environment = WorkingEnvironment.Remote; @@ -173,6 +194,10 @@ namespace Tango.MachineStudio.Common Theme = MachineStudioTheme.Light; JobUnitsMethod = JobUnitsMethods.Operator; ExternalBridgeRequestTimeout = TimeSpan.FromSeconds(5); + ExternalBridgeContinuousRequestTimeout = TimeSpan.FromSeconds(5); + ExternalBridgeSignalRHub = "ExternalBridgeHub"; + EnableExternalBridgeSignalR = true; + TcpTransportAdapterWriteMode = TcpTransportAdapterWriteMode.Interval; } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs index 92326f26f..eeafa513f 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs @@ -12,6 +12,7 @@ using Tango.AdvancedInstaller; using Tango.Core; using Tango.Core.Cryptography; using Tango.Core.Helpers; +using Tango.Git; using Tango.MachineStudio.Common.Web; using Tango.Transport.Web; using Tango.Web; @@ -255,6 +256,55 @@ namespace Tango.MachineStudio.Common.Publish throw new InvalidOperationException("The remote version does not seems to have been updated."); } + if (Options.CreateTag) + { + String repoPath = Path.GetFullPath("../../../../../"); + String tagVersion = System.Version.Parse(GetLocalVersion()).ToString(3); + String tagName = $"Machine_Studio_v{tagVersion}"; + + using (GitRepositoryManager git = new GitRepositoryManager(repoPath, Options.Email, Options.PersonalAccessToken)) + { + OnPublishProgress(0, 100, "Checking repository changes..."); + int changes = git.GetChanges().Count; + if (changes > 0) + { + if (Options.AutoCommitAndPush) + { + OnPublishProgress(0, 100, "Committing repository changes..."); + git.Commit(tagName); + } + else + { + throw new InvalidOperationException($"There are {changes} uncommitted changes on the repository. Please commit and push all changes before creating the Tag"); + } + } + + OnPublishProgress(0, 100, "Checking outgoing commits..."); + int commits = git.GetOutgoingCommits().Count; + if (commits > 0) + { + if (Options.AutoCommitAndPush) + { + OnPublishProgress(0, 100, "Pushing repository changes..."); + git.Sync(); + } + else + { + throw new InvalidOperationException($"There are {commits} outgoing commits on the repository. Please push all commits before creating the Tag"); + } + } + + git.Progress += (x, e) => + { + OnPublishProgress(e.Progress.Value, e.Progress.Maximum, $"Pushing Tag '{tagName}'..."); + }; + + OnPublishProgress(0, 100, $"Creating Tag '{tagName}'..."); + + git.CreatePushTag(tagName, Options.Comments, "Roy Ben Shabat"); + } + } + OnPublishProgress(0, 0, "Version published successfully."); } catch (Exception ex) diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishOptions.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishOptions.cs index c5db355b1..c0983eb8b 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishOptions.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishOptions.cs @@ -81,6 +81,27 @@ namespace Tango.MachineStudio.Common.Publish set { _installerOutputFolder = value; RaisePropertyChangedAuto(); } } + private String _personalAccessToken; + public String PersonalAccessToken + { + get { return _personalAccessToken; } + set { _personalAccessToken = value; RaisePropertyChangedAuto(); } + } + + private bool _createTag; + public bool CreateTag + { + get { return _createTag; } + set { _createTag = value; RaisePropertyChangedAuto(); } + } + + private bool _autoCommitAndSync; + public bool AutoCommitAndPush + { + get { return _autoCommitAndSync; } + set { _autoCommitAndSync = value; RaisePropertyChangedAuto(); } + } + public PublishOptions() { BasePath = AppDomain.CurrentDomain.BaseDirectory + "..\\"; diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml index 177a4fe75..d8e2017ec 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml @@ -4,12 +4,13 @@ xmlns:editors="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete" xmlns:dragAndDrop="clr-namespace:Tango.DragAndDrop;assembly=Tango.DragAndDrop" xmlns:sharedConverters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:mahApps="http://metro.mahapps.com/winfx/xaml/controls" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:Tango.MachineStudio.Common.Resources" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"> - + + + @@ -63,6 +66,13 @@ ../Fonts/#digital-7 + ../Fonts/#flexo + + + + + + @@ -526,23 +536,19 @@ - + - + - + @@ -561,29 +567,18 @@ - - - + + + - + - + @@ -650,7 +645,7 @@ Visibility="{Binding Path=(materialDesign:TextFieldAssist.DecorationVisibility), RelativeSource={RelativeSource TemplatedParent}}"/> - + @@ -774,6 +769,101 @@ + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs index 3e54a327b..fabe3e02f 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/StudioApplication/IStudioApplicationManager.cs @@ -20,6 +20,11 @@ namespace Tango.MachineStudio.Common.StudioApplication /// event EventHandler ApplicationReady; + /// + /// Occurs when the connected machine session has been lost and an automatic reconnection with the last machine is required. + /// + event EventHandler ReconnectionRequired; + /// /// Occurs when the connected machine property has changed. /// diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj index 7c0851d01..a14bb4e2a 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj @@ -59,6 +59,9 @@ ..\..\Referenced Assemblies\SMO\Microsoft.SqlServer.AzureStorageEnum.dll + + ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + @@ -83,6 +86,9 @@ + + Tup\PublishInfo.cs + GlobalVersionInfo.cs @@ -95,6 +101,11 @@ + + + + + @@ -117,6 +128,22 @@ + + + + + + + + + + + + + + + + @@ -271,6 +298,10 @@ {de2f2b86-025b-4f26-83a4-38bd48224ed5} Tango.Editors + + {99081c0e-065c-4d68-bf60-f82330cca02d} + Tango.Git + {4206ac58-3b57-4699-8835-90bf6db01a61} Tango.Integration @@ -291,6 +322,10 @@ {8491d07b-c1f6-4b62-a412-41b9fd2d6538} Tango.SharedUI + + {e1e66ed9-597d-45fa-8048-de90a6930484} + Tango.SQLExaminer + {74e700b0-1156-4126-be40-ee450d3c3026} Tango.Transport @@ -387,10 +422,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Themes/DarkThemeColors.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Themes/DarkThemeColors.xaml index 8dd4efc32..d9819e5ce 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Themes/DarkThemeColors.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Themes/DarkThemeColors.xaml @@ -171,6 +171,7 @@ #5C5C5C #5C5C5C #FF03A9F4 + #181818 @@ -269,6 +270,10 @@ + + + + + + - - - Logging you in... - - - + + + + + + Login to your account + + + + + + + + + + + + + + + + + + Environment selection requires restarting the application + Remember me + + + + + + + + + + + + Password change required + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml index 69ce4c855..78557a42e 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineConnectionView.xaml @@ -10,7 +10,7 @@ xmlns:emulations="clr-namespace:Tango.Emulations.ExternalBridge;assembly=Tango.Emulations" xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views" mc:Ignorable="d" - d:DesignHeight="300" d:DesignWidth="300" Width="630" Height="400" Background="{StaticResource Dialog.Background}" DataContext="{Binding MachineConnectionViewVM, Source={StaticResource Locator}}" Foreground="{StaticResource MainWindow.Foreground}"> + d:DesignHeight="300" d:DesignWidth="400" Width="700" Height="500" Background="{StaticResource Dialog.Background}" DataContext="{Binding MachineConnectionViewVM, Source={StaticResource Locator}}" Foreground="{StaticResource MainWindow.Foreground}"> @@ -27,7 +27,7 @@ - + @@ -55,10 +55,28 @@ + + + + + + + S/N: + + + Address: + + + Organization: + + + + + - + S/N: @@ -76,7 +94,7 @@ - + Port: @@ -91,7 +109,7 @@ - + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml index 7d0b2e25c..e4cdfe199 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineLoginView.xaml @@ -17,19 +17,26 @@ - - - - + + + + Require Safety Level Operations + + + + + + + - + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineSerialView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineSerialView.xaml index eea90c7b9..2393ab6e7 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineSerialView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MachineSerialView.xaml @@ -23,7 +23,7 @@ - + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml index d427be9e5..ea6e93412 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml @@ -47,51 +47,27 @@ - - + + + + + + + - - - - - - - - , - - - - - - - - - - - - - - - ... - - - - - - - - - - - - Home - - + MODULES @@ -99,7 +75,7 @@ - + + + + + + + + + + + + + + + + + + + + + @@ -307,6 +372,9 @@ + + + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml index ef9667b6d..aac712f59 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ReportIssueView.xaml @@ -12,7 +12,7 @@ xmlns:tfs="clr-namespace:Tango.TFS;assembly=Tango.TFS" xmlns:tfss="clr-namespace:Tango.MachineStudio.UI.TFS" xmlns:local="clr-namespace:Tango.MachineStudio.UI.Views" - mc:Ignorable="d" Width="530" Height="720" Background="{StaticResource Dialog.Background}" d:DataContext="{d:DesignInstance Type=vm:ReportIssueViewVM, IsDesignTimeCreatable=False}" Foreground="{StaticResource MainWindow.Foreground}"> + mc:Ignorable="d" Width="530" Height="660" Background="{StaticResource Dialog.Background}" d:DataContext="{d:DesignInstance Type=vm:ReportIssueViewVM, IsDesignTimeCreatable=False}" Foreground="{StaticResource MainWindow.Foreground}"> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ShutdownView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ShutdownView.xaml index cc1060b2a..6bda3fe2d 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ShutdownView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/ShutdownView.xaml @@ -10,7 +10,7 @@ - + Machine Studio diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml index 25fe4af5d..01f08491a 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ExceptionWindow.xaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Tango.MachineStudio.UI.Windows" mc:Ignorable="d" - WindowStyle="None" ResizeMode="NoResize" Topmost="True" AllowsTransparency="True" WindowStartupLocation="CenterScreen" Width="800" Height="600" Background="Transparent" d:DataContext="{d:DesignInstance Type=local:ExceptionWindow, IsDesignTimeCreatable=False}"> + WindowStyle="None" ResizeMode="NoResize" Topmost="True" AllowsTransparency="True" WindowStartupLocation="CenterScreen" Width="800" Height="600" Background="Transparent" d:DataContext="{d:DesignInstance Type=local:ExceptionWindow, IsDesignTimeCreatable=False}" FontFamily="{StaticResource flexo}" Foreground="{StaticResource Dialog.Foreground}"> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml index 47b36070a..5db0277cc 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml @@ -10,7 +10,7 @@ xmlns:views="clr-namespace:Tango.MachineStudio.UI.Views" xmlns:sharedControls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" mc:Ignorable="d" - Title="{Binding RelativeSource={RelativeSource Self},Path=ModuleContext.Module.Name}" Height="800" Width="1280" WindowStartupLocation="CenterOwner" WindowState="Maximized" Foreground="#494949" BorderThickness="1" BorderBrush="{StaticResource AccentColorBrush}"> + Title="Machine Studio" Height="800" Width="1280" WindowStartupLocation="CenterOwner" WindowState="Maximized" Foreground="#494949" BorderThickness="1" BorderBrush="{StaticResource AccentColorBrush}" FontFamily="{StaticResource flexo}"> @@ -29,8 +29,16 @@ - - + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs index 7ca062645..cfea78964 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Windows/ModuleWindow.xaml.cs @@ -12,6 +12,8 @@ using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; +using Tango.Core.DI; +using Tango.MachineStudio.Common.StudioApplication; using Tango.MachineStudio.UI.ViewModels; namespace Tango.MachineStudio.UI.Windows @@ -32,6 +34,13 @@ namespace Tango.MachineStudio.UI.Windows public ModuleWindow() { InitializeComponent(); + + ContentRendered += ModuleWindow_ContentRendered; + } + + private void ModuleWindow_ContentRendered(object sender, EventArgs e) + { + Title = "MACHINE STUDIO " + TangoIOC.Default.GetInstance().Version.ToString(3); } public ModuleWindow(MainViewVM mainViewVM, ModuleWindowVM moduleVM, FrameworkElement view) : this() diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/machine_new_small.ico b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/machine_new_small.ico new file mode 100644 index 000000000..dd159c221 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/machine_new_small.ico differ -- cgit v1.3.1