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" --- Software/Visual_Studio/PPC/Tango.PPC.UI/App.config | 7 +- .../Visual_Studio/PPC/Tango.PPC.UI/App.xaml.cs | 102 +++- .../Tango.PPC.UI/AppBarItems/PowerOffAppBarItem.cs | 31 ++ .../AppBarItems/PowerOffAppBarItemView.xaml | 30 ++ .../AppBarItems/PowerOffAppBarItemView.xaml.cs | 28 ++ .../Tango.PPC.UI/AppBarItems/PowerUpAppBarItem.cs | 31 ++ .../AppBarItems/PowerUpAppBarItemView.xaml | 30 ++ .../AppBarItems/PowerUpAppBarItemView.xaml.cs | 28 ++ .../DefaultAuthenticationProvider.cs | 18 + .../Connectivity/DefaultConnectivityProvider.cs | 44 +- .../Controls/MachineStatusControl.xaml | 49 ++ .../Controls/MachineStatusControl.xaml.cs | 28 ++ .../Dialogs/FirmwareUpgradeFromFileView.xaml | 28 ++ .../Dialogs/FirmwareUpgradeFromFileView.xaml.cs | 28 ++ .../Dialogs/FirmwareUpgradeFromFileViewVM.cs | 15 + .../Dialogs/InsufficientLiquidQuantityView.xaml | 62 ++- .../Dialogs/InsufficientLiquidQuantityView.xaml.cs | 6 +- .../PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml | 32 ++ .../PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml.cs | 34 ++ .../PPC/Tango.PPC.UI/Dialogs/PowerUpViewVM.cs | 128 +++++ .../SafetyLevelOperationsConfirmationView.xaml | 52 ++ .../SafetyLevelOperationsConfirmationView.xaml.cs | 28 ++ .../SafetyLevelOperationsConfirmationViewVM.cs | 82 ++++ .../PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml | 225 +++++++++ .../Tango.PPC.UI/Dialogs/ThreadBreakView.xaml.cs | 28 ++ .../PPC/Tango.PPC.UI/Dialogs/ThreadBreakViewVM.cs | 245 ++++++++++ .../Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml | 170 +++++++ .../Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml.cs | 28 ++ .../Tango.PPC.UI/Dialogs/ThreadLoadingViewVM.cs | 287 +++++++++++ .../Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml | 21 +- .../Tango.PPC.UI/Dialogs/UpdateFromFileViewVM.cs | 8 +- .../PPC/Tango.PPC.UI/Images/GlobalStatus/error.png | Bin 0 -> 810 bytes .../Images/GlobalStatus/getting-ready.png | Bin 0 -> 586 bytes .../Tango.PPC.UI/Images/GlobalStatus/service.png | Bin 0 -> 844 bytes .../Images/GlobalStatus/shutting-down.png | Bin 0 -> 1190 bytes .../PPC/Tango.PPC.UI/Images/Menu/backup.png | Bin 0 -> 1834 bytes .../Images/ThreadLoading/DryerClose/1.jpg | Bin 0 -> 57998 bytes .../Images/ThreadLoading/DryerClose/2.jpg | Bin 0 -> 58057 bytes .../Images/ThreadLoading/DryerClose/3.jpg | Bin 0 -> 59306 bytes .../Images/ThreadLoading/DryerClose/4.jpg | Bin 0 -> 55777 bytes .../Images/ThreadLoading/FeedingUnits/1.JPG | Bin 0 -> 50823 bytes .../Images/ThreadLoading/FeedingUnits/2.JPG | Bin 0 -> 36100 bytes .../Images/ThreadLoading/FeedingUnits/3.JPG | Bin 0 -> 52652 bytes .../Images/ThreadLoading/FeedingUnits/4.JPG | Bin 0 -> 62531 bytes .../Images/ThreadLoading/FeedingUnits/arc/1.jpg | Bin 0 -> 50823 bytes .../Images/ThreadLoading/FeedingUnits/arc/2.jpg | Bin 0 -> 36100 bytes .../Images/ThreadLoading/FeedingUnits/arc/3.jpg | Bin 0 -> 52652 bytes .../Images/ThreadLoading/FeedingUnits/arc/4.jpg | Bin 0 -> 62531 bytes .../Images/ThreadLoading/FeedingUnits/arc/5.jpg | Bin 0 -> 123123 bytes .../Images/ThreadLoading/GuidingUnits/1.JPG | Bin 0 -> 47345 bytes .../NewThread/ReadyForLoading/arc/1.jpg | Bin 0 -> 70545 bytes .../NewThread/ReadyForLoading/arc/2.JPG | Bin 0 -> 50823 bytes .../NewThread/ReadyForLoading/arc/3.JPG | Bin 0 -> 36100 bytes .../NewThread/ReadyForLoading/arc/4.JPG | Bin 0 -> 85970 bytes .../NewThread/ReadyForLoading/arc/5.JPG | Bin 0 -> 123123 bytes .../NewThread/ReadyForLoading/arc/6.JPG | Bin 0 -> 67829 bytes .../NewThread/ReadyForLoading/arc/7.jpg | Bin 0 -> 229536 bytes .../NewThread/TS1800_CloseUp_Feeder_P.jpg | Bin 0 -> 94899 bytes .../ThreadLoading/NewThread/machine_full.jpg | Bin 0 -> 67243 bytes .../Images/ThreadLoading/TheDryer/1.jpg | Bin 0 -> 39336 bytes .../Images/ThreadLoading/TheDryer/2.jpg | Bin 0 -> 36100 bytes .../Images/ThreadLoading/TheDryer/3.jpg | Bin 0 -> 45420 bytes .../Images/ThreadLoading/TheDryer/4.jpg | Bin 0 -> 46782 bytes .../Images/ThreadLoading/TheDryer/5.jpg | Bin 0 -> 49932 bytes .../PPC/Tango.PPC.UI/Images/backup-big.png | Bin 0 -> 3044 bytes .../PPC/Tango.PPC.UI/Images/backup-restore.png | Bin 0 -> 89496 bytes .../PPC/Tango.PPC.UI/Images/firmware.png | Bin 0 -> 3956 bytes .../PPC/Tango.PPC.UI/Images/loading_anim.gif | Bin 0 -> 798338 bytes .../PPC/Tango.PPC.UI/Images/machine-image.png | Bin 0 -> 138220 bytes .../PPC/Tango.PPC.UI/Images/power_off.gif | Bin 0 -> 397334 bytes .../PPC/Tango.PPC.UI/Images/power_off_2.gif | Bin 0 -> 32040 bytes .../PPC/Tango.PPC.UI/Images/powerup.gif | Bin 0 -> 380322 bytes .../PPC/Tango.PPC.UI/Images/restore.png | Bin 0 -> 3252 bytes .../PPC/Tango.PPC.UI/Images/thread_loading.gif | Bin 0 -> 4092741 bytes .../PPC/Tango.PPC.UI/Images/thread_loading.png | Bin 0 -> 7209 bytes .../Tango.PPC.UI/Images/thread_loading_preview.png | Bin 0 -> 529370 bytes .../PPC/Tango.PPC.UI/Images/update_available.png | Bin 0 -> 2856 bytes .../PPC/Tango.PPC.UI/InternalModule.cs | 84 ++++ .../PPC/Tango.PPC.UI/MainWindow.xaml.cs | 21 +- .../Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs | 156 ++++++ .../Modules/DefaultStudioModuleLoader.cs | 152 ------ .../Navigation/DefaultNavigationManager.cs | 382 ++++++++++----- .../Notifications/DefaultNotificationProvider.cs | 128 +++-- .../UpdateAvailableNotificationItem.cs | 52 ++ .../UpdateAvailableNotificationItemView.xaml | 30 ++ .../UpdateAvailableNotificationItemView.xaml.cs | 30 ++ .../PPCApplication/DefaultPPCApplicationManager.cs | 252 +++++++++- .../Printing/DefaultPrintingManager.cs | 6 +- .../PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs | 2 +- .../RemoteActions/DefaultRemoteActionsService.cs | 54 +++ .../PPC/Tango.PPC.UI/Resources/Colors.xaml | 2 + .../PPC/Tango.PPC.UI/Tango.PPC.UI.csproj | 223 ++++++++- .../ThreadLoading/DefaultThreadLoadingService.cs | 65 +++ .../PPC/Tango.PPC.UI/ViewModelLocator.cs | 84 +++- .../ViewModels/ExternalBridgeViewVM.cs | 52 +- .../ViewModels/InternalModuleViewVM.cs | 17 + .../PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs | 250 +++++++++- .../PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs | 65 +-- .../PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs | 8 +- .../Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs | 5 +- .../Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs | 536 ++++++++++++++++++++- .../PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs | 154 ++++++ .../PPC/Tango.PPC.UI/ViewModels/PowerOffViewVM.cs | 134 ++++++ .../Tango.PPC.UI/ViewModels/RestartingViewVM.cs | 27 ++ .../PPC/Tango.PPC.UI/Views/EmergencyView.xaml | 16 +- .../PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml | 19 +- .../PPC/Tango.PPC.UI/Views/InternalModuleView.xaml | 18 + .../Tango.PPC.UI/Views/InternalModuleView.xaml.cs | 28 ++ .../PPC/Tango.PPC.UI/Views/LayoutView.xaml | 131 +++-- .../PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs | 16 +- .../PPC/Tango.PPC.UI/Views/LoadingView.xaml | 11 +- .../PPC/Tango.PPC.UI/Views/MachineSetupView.xaml | 2 +- .../PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml | 5 +- .../Tango.PPC.UI/Views/MachineUpdateView.xaml.cs | 6 +- .../PPC/Tango.PPC.UI/Views/MainView.xaml | 58 ++- .../PPC/Tango.PPC.UI/Views/PowerOffView.xaml | 20 + .../PPC/Tango.PPC.UI/Views/PowerOffView.xaml.cs | 28 ++ .../Tango.PPC.UI/Views/RestartingSystemView.xaml | 40 +- .../PPC/Tango.PPC.UI/Views/RestartingView.xaml | 52 ++ .../PPC/Tango.PPC.UI/Views/RestartingView.xaml.cs | 28 ++ .../Visual_Studio/PPC/Tango.PPC.UI/app.manifest | 2 +- .../PPC/Tango.PPC.UI/firmware_package.tfp | Bin 0 -> 270787 bytes 122 files changed, 4838 insertions(+), 546 deletions(-) create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItem.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItem.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/error.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/getting-ready.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/service.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/shutting-down.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/Menu/backup.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/1.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/2.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/3.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/4.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/1.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/2.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/3.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/4.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/1.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/2.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/3.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/4.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/5.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/GuidingUnits/1.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/1.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/2.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/3.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/4.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/5.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/6.JPG create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/7.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/TS1800_CloseUp_Feeder_P.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/machine_full.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/1.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/2.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/3.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/4.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/5.jpg create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-big.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-restore.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/firmware.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-image.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off.gif create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/powerup.gif create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/restore.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.gif create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading_preview.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/update_available.png create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/InternalModule.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs delete mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItem.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/RemoteActions/DefaultRemoteActionsService.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/ThreadLoading/DefaultThreadLoadingService.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/InternalModuleViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/PowerOffViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/RestartingViewVM.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Views/InternalModuleView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Views/InternalModuleView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/firmware_package.tfp (limited to 'Software/Visual_Studio/PPC/Tango.PPC.UI') diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config index 77255b814..5272eb35d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config @@ -8,8 +8,13 @@ - + + + + + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.xaml.cs new file mode 100644 index 000000000..fdd7bfc30 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerOffAppBarItemView.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.PPC.UI.AppBarItems +{ + /// + /// Interaction logic for PowerOffAppBarItemView.xaml + /// + public partial class PowerOffAppBarItemView : UserControl + { + public PowerOffAppBarItemView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItem.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItem.cs new file mode 100644 index 000000000..966e78769 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItem.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR.Power; +using Tango.PPC.Common.Notifications; + +namespace Tango.PPC.UI.AppBarItems +{ + public class PowerUpAppBarItem : AppBarItem + { + private StartPowerUpResponse _status; + public StartPowerUpResponse Status + { + get { return _status; } + set { _status = value; RaisePropertyChangedAuto(); } + } + + /// + /// Gets or sets the view type. + /// + public override Type ViewType + { + get + { + return typeof(PowerUpAppBarItemView); + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml new file mode 100644 index 000000000..b6b769c69 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + % + Completed + + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.xaml.cs new file mode 100644 index 000000000..599f24d3b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/AppBarItems/PowerUpAppBarItemView.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.PPC.UI.AppBarItems +{ + /// + /// Interaction logic for PowerOffAppBarItemView.xaml + /// + public partial class PowerUpAppBarItemView : UserControl + { + public PowerUpAppBarItemView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs index 04e968da2..e7be61b0a 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Authentication/DefaultAuthenticationProvider.cs @@ -45,6 +45,11 @@ namespace Tango.PPC.UI.Authentication } } + /// + /// Gets a value indicating whether the authentication provider is using a null user. + /// + public bool AuthenticationRequired { get; private set; } + /// /// Performs a user login by the specified email and password. /// @@ -56,6 +61,9 @@ namespace Tango.PPC.UI.Authentication { return Task.Factory.StartNew(() => { + + AuthenticationRequired = true; + String hash = encrypt ? User.GetPasswordHash(password) : password; LogManager.Log($"Logging in user {email}..."); @@ -82,6 +90,16 @@ namespace Tango.PPC.UI.Authentication }); } + public Task Login() + { + return Task.Factory.StartNew(() => + { + AuthenticationRequired = false; + CurrentUser = null; + CurrentUserChanged?.Invoke(this, CurrentUser); + }); + } + /// /// Logs-out the current logged-in user. /// diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs index 53e143def..5218d9f70 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Connectivity/DefaultConnectivityProvider.cs @@ -4,6 +4,7 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -29,7 +30,9 @@ namespace Tango.PPC.UI.Connectivity private IMachineProvider _machineProvider; private Rfc2898Cryptographer _cryptographer; private System.Timers.Timer _updateTimer; + private System.Timers.Timer _lanUpdateTimer; private WiFiNetwork _connectedNetwork; + private PPCSettings _settings; /// /// Occurs when the connectivity provider state has changed (e.g network connected/disconnected). @@ -43,7 +46,17 @@ namespace Tango.PPC.UI.Connectivity public bool IsConnected { get { return _isConnected; } - set { _isConnected = value; RaisePropertyChangedAuto(); } + private set { _isConnected = value; RaisePropertyChangedAuto(); } + } + + private bool _isLanConnected; + /// + /// Gets a value indicating whether there is LAN connection. + /// + public bool IsLanConnected + { + get { return _isLanConnected; } + private set { _isLanConnected = value; RaisePropertyChangedAuto(); } } private bool _isHotspoActive; @@ -116,6 +129,8 @@ namespace Tango.PPC.UI.Connectivity { await RefreshAvailableWiFiNetworks(); }); + + _settings = SettingsManager.Default.GetOrCreate(); } /// @@ -153,6 +168,28 @@ namespace Tango.PPC.UI.Connectivity _updateTimer = new System.Timers.Timer(TimeSpan.FromSeconds(30).TotalMilliseconds); _updateTimer.Elapsed += _updateTimer_Elapsed; _updateTimer.Start(); + + _lanUpdateTimer = new System.Timers.Timer(TimeSpan.FromSeconds(10).TotalMilliseconds); + _lanUpdateTimer.Elapsed += _lanUpdateTimer_Elapsed; + _lanUpdateTimer.Start(); + } + + private void _lanUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + foreach (NetworkInterface net in NetworkInterface.GetAllNetworkInterfaces()) + { + if ((net.NetworkInterfaceType == NetworkInterfaceType.Ethernet + || net.NetworkInterfaceType == NetworkInterfaceType.Ethernet3Megabit + || net.NetworkInterfaceType == NetworkInterfaceType.FastEthernetFx + || net.NetworkInterfaceType == NetworkInterfaceType.FastEthernetT + || net.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet) && net.Name.ToStringOrEmpty().StartsWith("Ethernet") && net.OperationalStatus == OperationalStatus.Up) + { + IsLanConnected = true; + return; + } + } + + IsLanConnected = false; } /// @@ -223,6 +260,11 @@ namespace Tango.PPC.UI.Connectivity /// public Task CheckInternetConnection() { + if (_settings.BypassInternetConnectivityCheck) + { + return Task.FromResult(true); + } + return Task.Factory.StartNew(() => { try diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml new file mode 100644 index 000000000..3404c032a --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml @@ -0,0 +1,49 @@ + + + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.xaml.cs new file mode 100644 index 000000000..61ecef0ad --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Controls/MachineStatusControl.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.PPC.UI.Controls +{ + /// + /// Interaction logic for MachineStatusControl.xaml + /// + public partial class MachineStatusControl : UserControl + { + public MachineStatusControl() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml new file mode 100644 index 000000000..66bd0392d --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml @@ -0,0 +1,28 @@ + + + + + CANCEL + UPGRADE + + + + Tango Firmware Upgrade + The selected file contains a firmware upgrade package. Press 'UPGRADE' to start updating your system. + + + Firmware: + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.xaml.cs new file mode 100644 index 000000000..e7e1eb86c --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileView.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.PPC.UI.Dialogs +{ + /// + /// Interaction logic for UpdateFromFileView.xaml + /// + public partial class FirmwareUpgradeFromFileView : UserControl + { + public FirmwareUpgradeFromFileView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileViewVM.cs new file mode 100644 index 000000000..9a7322565 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/FirmwareUpgradeFromFileViewVM.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common.Publish; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class FirmwareUpgradeFromFileViewVM : DialogViewVM + { + public String Version { get; set; } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml index f3c471954..ad1c2ece3 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml @@ -3,7 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" + xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" mc:Ignorable="d" Background="{StaticResource TangoPrimaryBackgroundBrush}" Width="700" Height="800" d:DataContext="{d:DesignInstance Type=local:InsufficientLiquidQuantityViewVM, IsDesignTimeCreatable=False}"> @@ -20,28 +20,59 @@ The job cannot be completed. - + - + - - - + + + + + + + + + + + + + - + - - + + - + + + + + + + + + - + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml.cs index 9ec1eec0e..e0f02e4af 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/InsufficientLiquidQuantityView.xaml.cs @@ -33,7 +33,7 @@ namespace Tango.PPC.UI.Dialogs 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 = Math.Max(((double)packLevel.Current / (double)MachineOperator.MAX_DISPENSER_NANOLITER) * parent.ActualWidth, 0); } private void Limit_Loaded(object sender, RoutedEventArgs e) @@ -42,8 +42,8 @@ namespace Tango.PPC.UI.Dialogs 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/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml new file mode 100644 index 000000000..081778434 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml @@ -0,0 +1,32 @@ + + + + + Continue getting ready for: + + + + + + + Minimal temperature + + + CONTINUE + + + auto select in + + sec + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.xaml.cs new file mode 100644 index 000000000..a9767276a --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpView.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.PPC.UI.Dialogs +{ + /// + /// Interaction logic for PowerUpView.xaml + /// + public partial class PowerUpView : UserControl + { + public PowerUpView() + { + InitializeComponent(); + } + + protected override void OnPreviewMouseUp(MouseButtonEventArgs e) + { + base.OnPreviewMouseUp(e); + (DataContext as PowerUpViewVM).IsTimeoutEnabled = false; + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpViewVM.cs new file mode 100644 index 000000000..ec4b3bb2b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/PowerUpViewVM.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Timers; +using Tango.BL.Entities; +using Tango.PPC.Common; +using Tango.Settings; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class PowerUpViewVM : DialogViewVM + { + private Timer _timer; + + private List _rmls; + public List Rmls + { + get { return _rmls; } + set { _rmls = value; RaisePropertyChangedAuto(); } + } + + private Rml _selectedRml; + public Rml SelectedRml + { + get { return _selectedRml; } + set { _selectedRml = value; RaisePropertyChangedAuto(); } + } + + private bool _isSelectedRml; + public bool IsSelectedRml + { + get { return _isSelectedRml; } + set + { + _isSelectedRml = value; + RaisePropertyChangedAuto(); + + if (_isSelectedRml) + { + IsMinimalTemperature = false; + } + } + } + + private bool _isMinimalTemperature; + public bool IsMinimalTemperature + { + get { return _isMinimalTemperature; } + set + { + _isMinimalTemperature = value; + RaisePropertyChangedAuto(); + + if (_isMinimalTemperature) + { + IsSelectedRml = false; + } + } + } + + private int _remainingSeconds; + public int RemainingSeconds + { + get { return _remainingSeconds; } + set { _remainingSeconds = value; RaisePropertyChangedAuto(); } + } + + private bool _isTimeoutEnabled; + public bool IsTimeoutEnabled + { + get { return _isTimeoutEnabled; } + set + { + _isTimeoutEnabled = value; RaisePropertyChangedAuto(); + + if (!_isTimeoutEnabled) + { + _timer.Stop(); + } + } + } + + public PowerUpViewVM() + { + RemainingSeconds = (int)SettingsManager.Default.GetOrCreate().PowerUpScreenTimeout.TotalSeconds; + CanClose = true; + IsMinimalTemperature = true; + IsTimeoutEnabled = true; + _timer = new Timer(); + _timer.Interval = TimeSpan.FromSeconds(1).TotalMilliseconds; + _timer.Elapsed += _timer_Elapsed; + } + + private void _timer_Elapsed(object sender, ElapsedEventArgs e) + { + RemainingSeconds--; + + if (RemainingSeconds == 0) + { + InvokeUI(() => + { + Accept(); + }); + } + } + + protected override void Cancel() + { + _timer.Stop(); + base.Cancel(); + } + + protected override void Accept() + { + _timer.Stop(); + base.Accept(); + } + + public override void OnShow() + { + base.OnShow(); + _timer.Start(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml new file mode 100644 index 000000000..e96b39a63 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml @@ -0,0 +1,52 @@ + + + + + DECLINE + + + + + + + APPROVE + + + + Safety Level Access Request + + A remote client is requesting a safety level connection to this machine. + + Once approved, the remote user will be able to perform any mechanical operation remotely. + + + + + Request Information + + Address: + + + Host Name: + + + App ID: + + + User: + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.xaml.cs new file mode 100644 index 000000000..ef689f1de --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationView.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.PPC.UI.Dialogs +{ + /// + /// Interaction logic for SafetyLevelOperationsConfirmationView.xaml + /// + public partial class SafetyLevelOperationsConfirmationView : UserControl + { + public SafetyLevelOperationsConfirmationView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationViewVM.cs new file mode 100644 index 000000000..f8027b4c2 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/SafetyLevelOperationsConfirmationViewVM.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Threading; +using Tango.Integration.ExternalBridge; +using Tango.PMR.Integration; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class SafetyLevelOperationsConfirmationViewVM : DialogViewVM + { + private DispatcherTimer _timer; + + private int _maxSeconds; + public int MaxSeconds + { + get { return _maxSeconds; } + set { _maxSeconds = value; RaisePropertyChangedAuto(); } + } + + private int _secondsRemaining; + public int SecondsRemaining + { + get { return _secondsRemaining; } + set { _secondsRemaining = value; RaisePropertyChangedAuto(); } + } + + private ExternalBridgeClientConnectedEventArgs _connection; + /// + /// Gets or sets the last client connection event arguments. + /// + public ExternalBridgeClientConnectedEventArgs Connection + { + get { return _connection; } + set { _connection = value; RaisePropertyChangedAuto(); } + } + + public SafetyLevelOperationsConfirmationViewVM(ExternalBridgeClientConnectedEventArgs connection) + { + Connection = connection; + + MaxSeconds = 30; + SecondsRemaining = 30; + + _timer = new DispatcherTimer(DispatcherPriority.Background, Application.Current.Dispatcher); + _timer.Interval = TimeSpan.FromMilliseconds(800); + _timer.Tick += _timer_Tick; + } + + public override void OnShow() + { + base.OnShow(); + _timer.Start(); + } + + protected override void Accept() + { + _timer.Stop(); + base.Accept(); + } + + protected override void Cancel() + { + _timer.Stop(); + base.Cancel(); + } + + private void _timer_Tick(object sender, EventArgs e) + { + SecondsRemaining--; + + if (SecondsRemaining == 0) + { + Cancel(); + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml new file mode 100644 index 000000000..f17860d42 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml @@ -0,0 +1,225 @@ + + + + + + Thread Break Wizard + + + + + + + + + + Back + + + + + + + + + + + + Found But Can't Fix + Found and Fixed + Can't Find It + + + + Please check guiding units on both sides of the system and fix/tie the thread if possible. + + + + + + + + + + + + + + Found and Fixed + Can't Fix + + + if the thread is out of is route or tangle on one of the components you can go to the maintenance screen and open the component to solve the problem + + + + + Open the covers and check the feeder and puller and fix/tie if possible. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Removed Successfully + Can't Remove + + + + + HOT SURFACE! + + + Recommended to cool down and/or to wear safety gloves + + + + + + Open the dryer, cut the thread and remove any residue. + + + + + + + + + + + + + + + + + + + Open The Thread Loading Wizard + + + You will be able to open the thread loading wizard once the dryer door is closed + + + + + Close the dryer door + + + + + + + + + + + + + + + + + + Close + + + + + Please Contact Twine Customer Care + + + + + support@twine-s.com + + + + + + + + + + + + Verifying thread movement + + + + + working... + + + + + + + + + + + Close + + + + + Issue Resolved + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.xaml.cs new file mode 100644 index 000000000..c105a9a15 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakView.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.PPC.UI.Dialogs +{ + /// + /// Interaction logic for ThreadBreakWizard.xaml + /// + public partial class ThreadBreakView : UserControl + { + public ThreadBreakView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakViewVM.cs new file mode 100644 index 000000000..e737f3b12 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadBreakViewVM.cs @@ -0,0 +1,245 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Core.DI; +using Tango.Logging; +using Tango.PPC.Common.Connection; +using Tango.PPC.Common.Notifications; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class ThreadBreakViewVM : DialogViewVM + { + public enum ThreadBreakWizardResult + { + None, + StartThreadLoading + } + + public enum WizardStage + { + Welcome, + GuidingUnits, + FeedingUnits, + Jogging, + TheDryer, + DryerClose, + Fixed, + ContactSupport, + } + + [TangoInject] + private IMachineProvider MachineProvider { get; set; } + + [TangoInject] + private INotificationProvider NotificationProvider { get; set; } + + public ThreadBreakWizardResult Result { get; set; } + + private WizardStage _stage; + public WizardStage Stage + { + get { return _stage; } + set { _stage = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private bool _isArcHead; + public bool IsArcHead + { + get { return _isArcHead; } + set { _isArcHead = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand BackCommand { get; set; } + + //Guiding Units + public RelayCommand GuidingUnitsFoundCantFixCommand { get; set; } + public RelayCommand GuidingUnitsCantFindItCommand { get; set; } + public RelayCommand GuidingUnitsFoundAndFixedCommand { get; set; } + + //Feeding Units + public RelayCommand FeedingUnitsCantFixCommand { get; set; } + public RelayCommand FeedingUnitsFoundAndFixedCommand { get; set; } + + //The Dryer + public RelayCommand TheDryerCantRemoveCommand { get; set; } + public RelayCommand TheDryerRemovedSuccessfullyCommand { get; set; } + + //Dryer Close + public RelayCommand OpenThreadLoadingWizardCommand { get; set; } + + public ThreadBreakViewVM() + { + CanClose = true; + TangoIOC.Default.Inject(this); + + MachineProvider.MachineOperator.MachineEventsStateProvider.EventsChanged += MachineEventsStateProvider_EventsChanged; + MachineProvider.MachineDisconnected += MachineProvider_MachineDisconnected; + + IsArcHead = MachineProvider.Machine.MachineHeadType == BL.Enumerations.HeadTypes.Arc; + + BackCommand = new RelayCommand(GoBack, CanGoBack); + + //Guiding Units Commands + GuidingUnitsFoundCantFixCommand = new RelayCommand(GuidingUnitsFoundCantFix); + GuidingUnitsCantFindItCommand = new RelayCommand(GuidingUnitsCantFindIt); + GuidingUnitsFoundAndFixedCommand = new RelayCommand(GuidingUnitsFoundAndFixed); + + //Feeding Units Commands + FeedingUnitsCantFixCommand = new RelayCommand(FeedingUnitsCantFix); + FeedingUnitsFoundAndFixedCommand = new RelayCommand(FeedingUnitsFoundAndFixed); + + //The Dryer Commands + TheDryerRemovedSuccessfullyCommand = new RelayCommand(TheDryerRemovedSuccessfully); + TheDryerCantRemoveCommand = new RelayCommand(TheDryerCantRemove); + + OpenThreadLoadingWizardCommand = new RelayCommand(OpenThreadLoadingWizard, () => !MachineProvider.MachineOperator.MachineEventsStateProvider.Events.Any(x => x.Type == BL.Enumerations.EventTypes.DRYER_DOOR_OPEN)); + } + + private void MachineProvider_MachineDisconnected(object sender, EventArgs e) + { + InvokeUI(() => + { + Cancel(); + }); + } + + private void MachineEventsStateProvider_EventsChanged(object sender, IEnumerable e) + { + InvalidateRelayCommands(); + } + + #region Back + + private bool CanGoBack() + { + return Stage != WizardStage.GuidingUnits && + Stage != WizardStage.Jogging && + Stage != WizardStage.Fixed; + } + + private void GoBack() + { + switch (Stage) + { + case WizardStage.FeedingUnits: + Stage = WizardStage.GuidingUnits; + break; + case WizardStage.TheDryer: + Stage = WizardStage.GuidingUnits; + break; + case WizardStage.ContactSupport: + Stage = WizardStage.TheDryer; + break; + case WizardStage.DryerClose: + Stage = WizardStage.TheDryer; + break; + } + } + + #endregion + + #region Guiding Units Commands + + private async void GuidingUnitsFoundAndFixed() + { + Stage = WizardStage.Jogging; + + try + { + await MachineProvider.MachineOperator.AttemptThreadJogging(); + Stage = WizardStage.Fixed; + } + catch (Exception ex) + { + LogManager.Log(ex, LogCategory.Warning, "Error occurred while attempting to perform thread jogging."); + await NotificationProvider.ShowError($"Thread movement verification failed.\n{ex.FlattenMessage()}"); + Stage = WizardStage.FeedingUnits; + } + } + + private void GuidingUnitsCantFindIt() + { + Stage = WizardStage.FeedingUnits; + } + + private void GuidingUnitsFoundCantFix() + { + Stage = WizardStage.TheDryer; + } + + #endregion + + #region Feeding Units Commands + + private void FeedingUnitsCantFix() + { + Stage = WizardStage.TheDryer; + } + + private async void FeedingUnitsFoundAndFixed() + { + Stage = WizardStage.Jogging; + + try + { + await MachineProvider.MachineOperator.AttemptThreadJogging(); + Stage = WizardStage.Fixed; + } + catch (Exception ex) + { + LogManager.Log(ex, LogCategory.Warning, "Error occurred while attempting to perform thread jogging."); + await NotificationProvider.ShowError($"Thread movement verification failed.\n{ex.FlattenMessage()}"); + Stage = WizardStage.TheDryer; + } + } + + #endregion + + #region The Dryer Commands + + private void TheDryerCantRemove() + { + Stage = WizardStage.ContactSupport; + } + + private void TheDryerRemovedSuccessfully() + { + Stage = WizardStage.DryerClose; + } + + #endregion + + #region Dryer Close Commands + + private void OpenThreadLoadingWizard() + { + Result = ThreadBreakWizardResult.StartThreadLoading; + Accept(); + } + + #endregion + + protected override void Accept() + { + base.Accept(); + CleanUp(); + } + + protected override void Cancel() + { + base.Cancel(); + CleanUp(); + } + + private void CleanUp() + { + MachineProvider.MachineOperator.MachineEventsStateProvider.EventsChanged -= MachineEventsStateProvider_EventsChanged; + MachineProvider.MachineDisconnected -= MachineProvider_MachineDisconnected; + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml new file mode 100644 index 000000000..e45065c61 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml @@ -0,0 +1,170 @@ + + + + + + Thread Loading + + + + + + + + + Continue + + + + Welcome to the automatic thread loading wizard. + + + + Please ensure there are no thread residue in the system and press + continue + + + + + + + + + + + + + Continue + + + + + The system is now preparing... + + + + + + + + + + + + Continue + + + + + Please select the thread type you are going to load and press + continue + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Continue + + + + + The system is now loading the thread... + + + + + + + + + + + + + + Close + + + + Thread loading completed successfully! + + + + + + + + + + + Close + Retry + + + + Something went wrong, press 'retry' to try again + + + + + + + + + + + + Close + Retry + + + + Something went wrong, press 'retry' to try again + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.xaml.cs new file mode 100644 index 000000000..d4c737bcc --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingView.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.PPC.UI.Dialogs +{ + /// + /// Interaction logic for PowerUpView.xaml + /// + public partial class ThreadLoadingView : UserControl + { + public ThreadLoadingView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingViewVM.cs new file mode 100644 index 000000000..bb503e718 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/ThreadLoadingViewVM.cs @@ -0,0 +1,287 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Builders; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.Core.DI; +using Tango.Integration.Operation; +using Tango.PMR.ThreadLoading; +using Tango.PPC.Common; +using Tango.PPC.Common.Connection; +using Tango.PPC.Common.Notifications; +using Tango.Settings; +using Tango.SharedUI; + +namespace Tango.PPC.UI.Dialogs +{ + public class ThreadLoadingViewVM : DialogViewVM + { + public enum ThreadLoadingStage + { + Welcome, + Preparing, + ReadyForLoading, + Finalizing, + Completed, + PreparationError, + FinalizationError, + } + + [TangoInject] + private IMachineProvider MachineProvider { get; set; } + + [TangoInject] + private INotificationProvider NotificationProvider { get; set; } + + private PPCSettings _settings; + + private StartThreadLoadingResponse _status; + public StartThreadLoadingResponse Status + { + get { return _status; } + set { _status = value; RaisePropertyChangedAuto(); } + } + + private List _rmls; + public List Rmls + { + get { return _rmls; } + set { _rmls = value; RaisePropertyChangedAuto(); } + } + + private Rml _selectedRml; + public Rml SelectedRml + { + get { return _selectedRml; } + set { _selectedRml = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private ThreadLoadingStage _stage; + public ThreadLoadingStage Stage + { + get { return _stage; } + set { _stage = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private bool _isArcHead; + public bool IsArcHead + { + get { return _isArcHead; } + set { _isArcHead = value; RaisePropertyChangedAuto(); } + } + + private String _error; + public String Error + { + get { return _error; } + set { _error = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand ContinueCommand { get; set; } + public RelayCommand AbortCommand { get; set; } + + public ThreadLoadingViewVM(bool userInvoked = false) + { + CanClose = false; + + TangoIOC.Default.Inject(this); + _settings = SettingsManager.Default.GetOrCreate(); + + MachineProvider.MachineOperator.ThreadLoadingStatusChanged += MachineOperator_ThreadLoadingStatusChanged; + MachineProvider.MachineDisconnected += MachineProvider_MachineDisconnected; + + IsArcHead = MachineProvider.Machine.MachineHeadType == BL.Enumerations.HeadTypes.Arc; + + ContinueCommand = new RelayCommand(Continue, CanContinue); + AbortCommand = new RelayCommand(Abort); + + AdaptToState(userInvoked); + } + + private void MachineProvider_MachineDisconnected(object sender, EventArgs e) + { + InvokeUI(() => + { + Cancel(); + }); + } + + private void AdaptToState(bool userInvoked = false) + { + var status = MachineProvider.MachineOperator.ThreadLoadingStatus; + + if (status != null) + { + if (status.State == ThreadLoadingState.Preparing) + { + Stage = ThreadLoadingStage.Preparing; + } + else if (status.State == ThreadLoadingState.ReadyForLoading) + { + Stage = ThreadLoadingStage.ReadyForLoading; + } + else if (status.State == ThreadLoadingState.Finalizing) + { + Stage = ThreadLoadingStage.Finalizing; + } + else if (status.State == ThreadLoadingState.PreparationError) + { + OnPreparationError(status.ErrorReason); + } + else if (status.State == ThreadLoadingState.FinalizationError) + { + OnFinalizationError(status.ErrorReason); + } + else if (status.State == ThreadLoadingState.Completed) + { + if (userInvoked) + { + Stage = ThreadLoadingStage.Welcome; + } + else + { + Stage = ThreadLoadingStage.Completed; + } + } + } + } + + private void MachineOperator_ThreadLoadingStatusChanged(object sender, StartThreadLoadingResponse e) + { + Status = e; + AdaptToState(); + } + + private void Continue() + { + if (Stage == ThreadLoadingStage.Welcome) + { + Stage = ThreadLoadingStage.Preparing; + StartPreparing(); + } + else if (Stage == ThreadLoadingStage.ReadyForLoading) + { + ContinueThreadLoading(); + } + else if (Stage == ThreadLoadingStage.Completed) + { + Accept(); + } + else if (Stage == ThreadLoadingStage.PreparationError) + { + Stage = ThreadLoadingStage.Preparing; + StartPreparing(); + } + else if (Stage == ThreadLoadingStage.FinalizationError) + { + ContinueThreadLoading(); + } + } + + private async void StartPreparing() + { + try + { + await MachineProvider.MachineOperator.StartThreadLoading(); + } + catch (Exception ex) + { + OnPreparationError(ex.Message); + } + } + + private async void ContinueThreadLoading() + { + try + { + Stage = ThreadLoadingStage.Finalizing; + await MachineProvider.MachineOperator.ContinueThreadLoading(SelectedRml.GetActiveProcessGroup().ProcessParametersTables.FirstOrDefault()); + } + catch (Exception ex) + { + OnFinalizationError(ex.Message); + } + } + + private bool CanContinue() + { + bool canContinue = false; + + if (Stage != ThreadLoadingStage.Preparing && Stage != ThreadLoadingStage.Finalizing) + { + canContinue = true; + } + + if (Stage == ThreadLoadingStage.ReadyForLoading && SelectedRml == null) + { + canContinue = false; + } + + return canContinue; + } + + private void OnPreparationError(String error) + { + Error = error; + Stage = ThreadLoadingStage.PreparationError; + } + + private void OnFinalizationError(String error) + { + Error = error; + Stage = ThreadLoadingStage.FinalizationError; + } + + private void Abort() + { + Cancel(); + } + + public async override void OnShow() + { + base.OnShow(); + + LogManager.Log("Loading site RMLS..."); + + List rmls = new List(); + + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + rmls = await new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).WithActiveParametersGroup().BuildListAsync(); + } + + var selectedRml = rmls.SingleOrDefault(x => x.Guid == _settings.LoadedRmlGuid); + + Rmls = rmls; + SelectedRml = selectedRml != null ? selectedRml : rmls.FirstOrDefault(); + } + + protected override void Cancel() + { + CleanUp(); + base.Cancel(); + } + + protected override void Accept() + { + CleanUp(); + base.Accept(); + } + + private void CleanUp() + { + MachineProvider.MachineOperator.ThreadLoadingStatusChanged -= MachineOperator_ThreadLoadingStatusChanged; + MachineProvider.MachineDisconnected -= MachineProvider_MachineDisconnected; + + if (SelectedRml != null) + { + _settings.LoadedRmlGuid = SelectedRml.Guid; + _settings.Save(); + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml index 231f5dabb..6f70b954d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml @@ -6,21 +6,24 @@ xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" mc:Ignorable="d" - Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="550" Height="450" d:DataContext="{d:DesignInstance Type=local:UpdateFromFileViewVM, IsDesignTimeCreatable=False}"> + Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="570" Height="700" d:DataContext="{d:DesignInstance Type=local:UpdateFromFileViewVM, IsDesignTimeCreatable=False}"> - - CANCEL - UPDATE - + + CANCEL + UPDATE + - UPDATE PACKAGE + Tango Update Package The selected file contains a software update package. Press 'UPDATE' to start updating your system. - - Version - + + Application: + + + Firmware: + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileViewVM.cs index b9e876809..a38b0431a 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileViewVM.cs @@ -3,12 +3,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.PPC.Common.Publish; using Tango.SharedUI; namespace Tango.PPC.UI.Dialogs { public class UpdateFromFileViewVM : DialogViewVM { - public String Version { get; set; } + public PublishInfo PublishInfo { get; set; } + + public String FirmwareVersion + { + get { return PublishInfo.GetFirmwareVersion(); } + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/error.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/error.png new file mode 100644 index 000000000..b4b50e4ac Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/error.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/getting-ready.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/getting-ready.png new file mode 100644 index 000000000..a0dc77f92 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/getting-ready.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/service.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/service.png new file mode 100644 index 000000000..ba351ee66 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/service.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/shutting-down.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/shutting-down.png new file mode 100644 index 000000000..9aa8e2db6 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/GlobalStatus/shutting-down.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/Menu/backup.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/Menu/backup.png new file mode 100644 index 000000000..158bab095 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/Menu/backup.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/1.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/1.jpg new file mode 100644 index 000000000..3b2f58620 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/1.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/2.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/2.jpg new file mode 100644 index 000000000..a2f5ae568 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/2.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/3.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/3.jpg new file mode 100644 index 000000000..6069e9c29 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/3.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/4.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/4.jpg new file mode 100644 index 000000000..7588d68e2 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/DryerClose/4.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/1.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/1.JPG new file mode 100644 index 000000000..68921f1ca Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/1.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/2.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/2.JPG new file mode 100644 index 000000000..a8b5d9ba4 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/2.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/3.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/3.JPG new file mode 100644 index 000000000..407f1eae6 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/3.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/4.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/4.JPG new file mode 100644 index 000000000..52063b213 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/4.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/1.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/1.jpg new file mode 100644 index 000000000..68921f1ca Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/1.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/2.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/2.jpg new file mode 100644 index 000000000..a8b5d9ba4 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/2.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/3.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/3.jpg new file mode 100644 index 000000000..407f1eae6 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/3.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/4.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/4.jpg new file mode 100644 index 000000000..52063b213 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/4.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/5.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/5.jpg new file mode 100644 index 000000000..fa2c8312d Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/FeedingUnits/arc/5.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/GuidingUnits/1.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/GuidingUnits/1.JPG new file mode 100644 index 000000000..8d58771d4 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/GuidingUnits/1.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/1.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/1.jpg new file mode 100644 index 000000000..81aa412ec Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/1.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/2.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/2.JPG new file mode 100644 index 000000000..68921f1ca Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/2.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/3.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/3.JPG new file mode 100644 index 000000000..a8b5d9ba4 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/3.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/4.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/4.JPG new file mode 100644 index 000000000..9f200198d Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/4.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/5.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/5.JPG new file mode 100644 index 000000000..fa2c8312d Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/5.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/6.JPG b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/6.JPG new file mode 100644 index 000000000..7956b0695 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/6.JPG differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/7.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/7.jpg new file mode 100644 index 000000000..4ca8677cd Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/ReadyForLoading/arc/7.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/TS1800_CloseUp_Feeder_P.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/TS1800_CloseUp_Feeder_P.jpg new file mode 100644 index 000000000..f41898bc1 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/TS1800_CloseUp_Feeder_P.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/machine_full.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/machine_full.jpg new file mode 100644 index 000000000..212edc547 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/NewThread/machine_full.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/1.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/1.jpg new file mode 100644 index 000000000..d8da5726d Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/1.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/2.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/2.jpg new file mode 100644 index 000000000..a8b5d9ba4 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/2.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/3.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/3.jpg new file mode 100644 index 000000000..86dd6f397 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/3.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/4.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/4.jpg new file mode 100644 index 000000000..9d36f3642 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/4.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/5.jpg b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/5.jpg new file mode 100644 index 000000000..6ac67aa46 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/ThreadLoading/TheDryer/5.jpg differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-big.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-big.png new file mode 100644 index 000000000..3a712af49 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-big.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-restore.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-restore.png new file mode 100644 index 000000000..15be3b163 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/backup-restore.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/firmware.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/firmware.png new file mode 100644 index 000000000..af3ea4850 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/firmware.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif new file mode 100644 index 000000000..793007cc4 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-image.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-image.png new file mode 100644 index 000000000..277599070 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/machine-image.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off.gif new file mode 100644 index 000000000..dd07593e2 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off.gif differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif new file mode 100644 index 000000000..867107140 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/powerup.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/powerup.gif new file mode 100644 index 000000000..f435d38d1 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/powerup.gif differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/restore.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/restore.png new file mode 100644 index 000000000..e60aaf425 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/restore.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.gif new file mode 100644 index 000000000..b6a974084 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.gif differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.png new file mode 100644 index 000000000..5d536e7ae Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading_preview.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading_preview.png new file mode 100644 index 000000000..9bbea3368 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/thread_loading_preview.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/update_available.png b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/update_available.png new file mode 100644 index 000000000..c95dfa015 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/update_available.png differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/InternalModule.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/InternalModule.cs new file mode 100644 index 000000000..e960fa020 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/InternalModule.cs @@ -0,0 +1,84 @@ +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.PPC.Common; +using Tango.PPC.UI.Views; + +namespace Tango.PPC.UI +{ + [PPCModule(100)] + public class InternalModule : PPCModuleBase + { + public InternalModule() + { + IsVisibleInMenu = false; + } + + /// + /// Gets the module name. + /// + public override string Name + { + get + { + return "Internal"; + } + } + + /// + /// Gets the module description. + /// + public override string Description + { + get + { + return "Internal Module"; + } + } + + /// + /// Gets the module cover image. + /// + public override BitmapSource Image + { + get + { + return null; + } + } + + /// + /// Gets the module entry point view type. + /// + public override Type MainViewType + { + get + { + return typeof(InternalModuleView); + } + } + + /// + /// Gets the permission required to see and load this module. + /// + public override Permissions Permission + { + get + { + return Permissions.RunPPC; + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public override void Dispose() + { + //Dispose module here... + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs index b90a1afff..bf621ff2e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/MainWindow.xaml.cs @@ -61,6 +61,12 @@ namespace Tango.PPC.UI has_touch = true; } } + +#if !DEBUG + ForceTouch(); + has_touch = true; +#endif + #endif if (!has_touch) @@ -72,7 +78,7 @@ namespace Tango.PPC.UI gridMain.Height = 1280; viewBox.Child = gridMain; LockAspectRatio(); - this.SizeChanged += (x, y) => + this.SizeChanged += (x, y) => { LockAspectRatio(); }; @@ -81,6 +87,18 @@ namespace Tango.PPC.UI Closing += MainWindow_Closing; } + private void ForceTouch() + { + WindowStyle = WindowStyle.None; + ResizeMode = ResizeMode.NoResize; + WindowStartupLocation = WindowStartupLocation.Manual; + Topmost = false; // sure? + Left = 0; + Top = 0; + Width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width; + Height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height; + } + protected override void OnSourceInitialized(EventArgs e) { //var hwndSource = PresentationSource.FromVisual(this) as HwndSource; @@ -98,6 +116,7 @@ namespace Tango.PPC.UI private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { + e.Cancel = true; TangoIOC.Default.GetInstance().ShutDown(); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs new file mode 100644 index 000000000..bbabed225 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultPPCModuleLoader.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.BL.Entities; +using Tango.Logging; +using Tango.PPC.Common.Authentication; +using Tango.PPC.Common.Modules; +using Tango.PPC.Common; +using Tango.PPC.Jobs; +using System.Windows.Data; +using Tango.Core.DI; + +namespace Tango.PPC.UI.Modules +{ + /// + /// Represents the default PPC . + /// + /// + /// + public class DefaultPPCModuleLoader : ExtendedObject, IPPCModuleLoader + { + private static object _syncObject = new object(); + private IAuthenticationProvider _authenticationProvider; + private bool _loaded; + + /// + /// Occurs when the user has logged in and user modules are loaded. + /// + public event EventHandler ModulesLoaded; + + /// + /// Initializes a new instance of the class. + /// + /// The authentication provider. + public DefaultPPCModuleLoader(IAuthenticationProvider authenticationProvider) + { + _authenticationProvider = authenticationProvider; + AllModules = new ObservableCollection(); + UserModules = new ObservableCollection(); + + BindingOperations.EnableCollectionSynchronization(UserModules, _syncObject); + + _authenticationProvider.CurrentUserChanged += _authenticationProvider_CurrentUserChanged; + } + + /// + /// Handles the authentication provider user changed event. + /// + /// The sender. + /// The e. + private void _authenticationProvider_CurrentUserChanged(object sender, User e) + { + LoadModules(); + } + + private ObservableCollection _allModules; + /// + /// Gets all loaded modules. + /// + public ObservableCollection AllModules + { + get { return _allModules; } + private set { _allModules = value; RaisePropertyChangedAuto(); } + } + + private ObservableCollection _userModules; + /// + /// Gets all the user permitted modules. + /// + public ObservableCollection UserModules + { + get { return _userModules; } + private set { _userModules = value; RaisePropertyChangedAuto(); } + } + + /// + /// Loads all available PPC modules. + /// + public void LoadModules() + { + if (!_loaded) + { + //Preloaded + LogManager.Log(String.Format("Loading module '{0}'...", nameof(JobsModule))); + AllModules.Add(new JobsModule()); + //Preloaded + + AllModules.Clear(); + string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + + foreach (var file in Directory.GetFiles(assemblyFolder, "*.dll").Where(x => x.Contains("Tango.PPC"))) + { + try + { + Assembly moduleAssembly = null; + moduleAssembly = Assembly.LoadFrom(file); + + if (moduleAssembly != null) + { + foreach (var moduleType in moduleAssembly.GetLoadableTypes().Where(x => !x.IsInterface && typeof(IPPCModule).IsAssignableFrom(x) && !x.IsAbstract)) + { + if (!AllModules.ToList().Exists(x => x.GetType() == moduleType)) + { + try + { + LogManager.Log(String.Format("Loading module '{0}'...", moduleType.Name)); + var module = Activator.CreateInstance(moduleType) as IPPCModule; + AllModules.Add(module); + } + catch (Exception ex) + { + LogManager.Log(ex, "Could not load module " + moduleType.Name); + } + } + } + } + } + catch { } + } + + _loaded = true; + } + + AllModules = AllModules.OrderBy(x => x.GetType().GetCustomAttribute().Index).ToObservableCollection(); + + UserModules.Clear(); + + if (_authenticationProvider.AuthenticationRequired && _authenticationProvider.CurrentUser != null) + { + UserModules = AllModules.Where(x => _authenticationProvider.CurrentUser.HasPermission(x.Permission)).ToObservableCollection(); + } + else if (!_authenticationProvider.AuthenticationRequired) + { + UserModules = AllModules.ToObservableCollection(); + } + + ModulesLoaded?.Invoke(this, new EventArgs()); + } + + /// + /// Gets the PPC module of type T if loaded. + /// + /// + /// + public T GetPPCModule() where T : IPPCModule + { + return UserModules.OfType().FirstOrDefault(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs deleted file mode 100644 index feb7e371f..000000000 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Modules/DefaultStudioModuleLoader.cs +++ /dev/null @@ -1,152 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using Tango.Core; -using Tango.BL.Entities; -using Tango.Logging; -using Tango.PPC.Common.Authentication; -using Tango.PPC.Common.Modules; -using Tango.PPC.Common; -using Tango.PPC.Jobs; -using System.Windows.Data; -using Tango.Core.DI; - -namespace Tango.PPC.UI.Modules -{ - /// - /// Represents the default PPC . - /// - /// - /// - public class DefaultPPCModuleLoader : ExtendedObject, IPPCModuleLoader - { - private static object _syncObject = new object(); - private IAuthenticationProvider _authenticationProvider; - private bool _loaded; - - /// - /// Occurs when the user has logged in and user modules are loaded. - /// - public event EventHandler ModulesLoaded; - - /// - /// Initializes a new instance of the class. - /// - /// The authentication provider. - public DefaultPPCModuleLoader(IAuthenticationProvider authenticationProvider) - { - _authenticationProvider = authenticationProvider; - AllModules = new ObservableCollection(); - UserModules = new ObservableCollection(); - - BindingOperations.EnableCollectionSynchronization(UserModules, _syncObject); - - _authenticationProvider.CurrentUserChanged += _authenticationProvider_CurrentUserChanged; - } - - /// - /// Handles the authentication provider user changed event. - /// - /// The sender. - /// The e. - private void _authenticationProvider_CurrentUserChanged(object sender, User e) - { - LoadModules(); - } - - private ObservableCollection _allModules; - /// - /// Gets all loaded modules. - /// - public ObservableCollection AllModules - { - get { return _allModules; } - private set { _allModules = value; RaisePropertyChangedAuto(); } - } - - private ObservableCollection _userModules; - /// - /// Gets all the user permitted modules. - /// - public ObservableCollection UserModules - { - get { return _userModules; } - private set { _userModules = value; RaisePropertyChangedAuto(); } - } - - /// - /// Loads all available PPC modules. - /// - public void LoadModules() - { - if (!_loaded) - { - //Preloaded - LogManager.Log(String.Format("Loading module '{0}'...", nameof(JobsModule))); - AllModules.Add(new JobsModule()); - //Preloaded - - AllModules.Clear(); - string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - - foreach (var file in Directory.GetFiles(assemblyFolder, "*.dll").Where(x => x.Contains("Tango.PPC"))) - { - try - { - Assembly moduleAssembly = null; - moduleAssembly = Assembly.LoadFrom(file); - - if (moduleAssembly != null) - { - foreach (var moduleType in moduleAssembly.GetTypes().Where(x => !x.IsInterface && typeof(IPPCModule).IsAssignableFrom(x) && !x.IsAbstract)) - { - if (!AllModules.ToList().Exists(x => x.GetType() == moduleType)) - { - try - { - LogManager.Log(String.Format("Loading module '{0}'...", moduleType.Name)); - var module = Activator.CreateInstance(moduleType) as IPPCModule; - AllModules.Add(module); - } - catch (Exception ex) - { - LogManager.Log(ex, "Could not load module " + moduleType.Name); - } - } - } - } - } - catch { } - } - - _loaded = true; - } - - AllModules = AllModules.OrderBy(x => x.GetType().GetCustomAttribute().Index).ToObservableCollection(); - - UserModules.Clear(); - - if (_authenticationProvider.CurrentUser != null) - { - UserModules = AllModules.Where(x => _authenticationProvider.CurrentUser.HasPermission(x.Permission)).ToObservableCollection(); - } - - ModulesLoaded?.Invoke(this, new EventArgs()); - } - - /// - /// Gets the PPC module of type T if loaded. - /// - /// - /// - public T GetPPCModule() where T : IPPCModule - { - return UserModules.OfType().FirstOrDefault(); - } - } -} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs index fe3cabcc1..d247ab23c 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; @@ -12,6 +13,7 @@ using Tango.Core.Commands; using Tango.PPC.Common; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; +using Tango.PPC.Common.Notifications; using Tango.PPC.Common.Threading; using Tango.PPC.UI.Views; using Tango.SharedUI.Controls; @@ -24,23 +26,49 @@ namespace Tango.PPC.UI.Navigation /// public class DefaultNavigationManager : ExtendedObject, INavigationManager { - private event Action NavigationCycleCompleted; + //private event Action NavigationCycleCompleted; + //private event Action BeforeNavigationCycleCompleted; + private class AwaitingVMResult + { + public PPCViewModel FromVM { get; set; } + public PPCViewModel ToVM { get; set; } + public Action Action { get; set; } + } + private List _awaitingVMResults; private IDispatcherProvider _dispatcherProvider; private IPPCModuleLoader _moduleLoader; - private Object _currentVM; + private INotificationProvider _notificationProvider; private String _lastFullPath; private bool _preventHistory; private bool _navigating_back; + public event EventHandler CurrentVMChanged; + private Stack _navigationHistory; + private Object _currentVM; /// /// Gets the current view model. /// public PPCViewModel CurrentVM { - get { return _currentVM as PPCViewModel; } + set + { + var previous = _currentVM; + _currentVM = value; + + var vm = _currentVM as PPCViewModel; + + if (_currentVM != previous && vm != null) + { + CurrentVMChanged?.Invoke(this, vm); + } + } + get + { + return _currentVM as PPCViewModel; + } } private IPPCModule _currentModule; @@ -67,10 +95,13 @@ namespace Tango.PPC.UI.Navigation /// Initializes a new instance of the class. /// /// The module loader. - public DefaultNavigationManager(IPPCModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider) + public DefaultNavigationManager(IPPCModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider, INotificationProvider notificationProvider) { + IsBackEnabled = true; + _awaitingVMResults = new List(); _navigationHistory = new Stack(); _moduleLoader = moduleLoader; + _notificationProvider = notificationProvider; NavigateToCommand = new RelayCommand(async (x) => await NavigateTo(x)); NavigateBackCommand = new RelayCommand(async () => await NavigateBack()); @@ -113,7 +144,19 @@ namespace Tango.PPC.UI.Navigation { LogManager.Log($"Navigating to: {view.ToString()}..."); - MainView.Instance.NavigationControl.NavigateTo(view.ToString()); + + var fromView = MainView.Instance.NavigationControl.SelectedElement; + FrameworkElement toView = null; + + toView = MainView.Instance.NavigationControl.NavigateTo(view.ToString(), (Action)(() => + { + CurrentVM = toView.DataContext as PPCViewModel; + NotifyOnNavigated(fromView.DataContext, toView.DataContext); + + })); + + NotifyOnBeforeNavigated(fromView.DataContext, toView.DataContext); + return Task.FromResult(true); } } @@ -173,88 +216,155 @@ namespace Tango.PPC.UI.Navigation /// Navigates to the specified module and view by full path (e.g Jobs.JobsView). /// /// The full path. - public async Task NavigateTo(String fullPath, bool pushToHistory = true) + public async Task NavigateTo(String fullPath, bool pushToHistory = true, Action onNavigating = null, Action onNavigated = null) { - String[] path = fullPath.Split('.'); - var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]); + try + { + IsNavigating = true; - if (path.Length == 1 && path[0] == CurrentModule.Name) return true; + String[] path = fullPath.Split('.'); + var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]); - LogManager.Log($"Navigating to: {fullPath}..."); + if (module == null) + { + await _notificationProvider.ShowError("The specified module was not loaded."); + IsNavigating = false; + return false; + } - var fromVM = _currentVM; + if (path.Length == 1 && path[0] == CurrentModule.Name) + { + IsNavigating = false; + return true; + } - if (_currentVM != null && _currentVM is INavigationBlocker) - { - if (_navigating_back) + LogManager.Log($"Navigating to: {fullPath}..."); + + var fromVM = CurrentVM; + + if (CurrentVM != null && CurrentVM is INavigationBlocker) { - if (!await (_currentVM as INavigationBlocker).OnNavigateBackRequest()) + if (_navigating_back) { - return false; + if (!await (CurrentVM as INavigationBlocker).OnNavigateBackRequest()) + { + IsNavigating = false; + return false; + } } - } - else - { - if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest()) + else { - return false; + if (!await (CurrentVM as INavigationBlocker).OnNavigateOutRequest()) + { + IsNavigating = false; + return false; + } } } - } - if (pushToHistory && _lastFullPath != null && !_preventHistory) - { - _navigationHistory.Push(_lastFullPath); - RaisePropertyChanged(nameof(CanNavigateBack)); - } - _lastFullPath = fullPath; - MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); - var navigationControl = LayoutView.Instance.NavigationControl; - CurrentModule = module; - var moduleView = navigationControl.NavigateTo(module.Name); + if (pushToHistory && _lastFullPath != null && !_preventHistory) + { + _navigationHistory.Push(_lastFullPath); + RaisePropertyChanged(nameof(CanNavigateBack)); + } - _currentVM = moduleView.DataContext; + _lastFullPath = fullPath; - if (path.Length > 1) - { - var moduleNavigation = moduleView.FindChildOffline(); + MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); + var navigationControl = LayoutView.Instance.NavigationControl; + CurrentModule = module; + var moduleView = navigationControl.NavigateTo(module.Name); + + CurrentVM = moduleView.DataContext as PPCViewModel; - if (moduleNavigation != null) + if (path.Length > 1) { - moduleNavigation.RegisterForLoadedOrNow(async (x, e) => + var moduleNavigation = moduleView.FindChildOffline(); + + if (moduleNavigation != null) { - foreach (var view in path.Skip(1)) + moduleNavigation.RegisterForLoadedOrNow(async (x, e) => { - await Task.Delay(100); - var v = moduleNavigation.NavigateTo(view); + var lastView = moduleNavigation.GetElement(path.Last()); + + if (lastView != null) + { + onNavigating?.Invoke(fromVM as PPCViewModel, lastView.DataContext as PPCViewModel); + } - if (v != null) + foreach (var view in path.Skip(1)) { - _currentVM = v.DataContext; + await Task.Delay(100); + + FrameworkElement v = null; - if (view != path.Last()) + v = moduleNavigation.NavigateTo(view, () => { - moduleNavigation = v.FindChildOffline(); + if (v != null) + { + NotifyOnNavigated(fromVM, v.DataContext); + onNavigated?.Invoke(fromVM as PPCViewModel, v.DataContext as PPCViewModel); + NotifyAwaitingVMResults(fromVM as PPCViewModel, v.DataContext as PPCViewModel); + } + }); + + NotifyOnBeforeNavigated(fromVM, v.DataContext); + + if (v != null) + { + CurrentVM = v.DataContext as PPCViewModel; + + if (view != path.Last()) + { + moduleNavigation = v.FindChildOffline(); + } + } + else + { + throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath)); } } - else - { - throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath)); - } - } + }); + } + else + { + onNavigating?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + + NotifyOnBeforeNavigated(fromVM, CurrentVM); + + await Task.Delay(navigationControl.TransitionDuration.TimeSpan); + + NotifyOnNavigated(fromVM, CurrentVM); - NavigationCycleCompleted?.Invoke(fromVM, _currentVM); - }); + onNavigated?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + NotifyAwaitingVMResults(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + } } else { - NavigationCycleCompleted?.Invoke(fromVM, _currentVM); + NotifyOnBeforeNavigated(fromVM, CurrentVM); + + onNavigating?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + + await Task.Delay(navigationControl.TransitionDuration.TimeSpan); + + NotifyOnNavigated(fromVM, CurrentVM); + + onNavigated?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + NotifyAwaitingVMResults(fromVM as PPCViewModel, CurrentVM as PPCViewModel); } - } - return true; + return true; + } + catch (Exception ex) + { + IsNavigating = false; + LogManager.Log(ex, $"Error navigating to '{fullPath}'."); + await _notificationProvider.ShowError($"Error navigating to '{fullPath}'."); + return false; + } } /// @@ -267,46 +377,35 @@ namespace Tango.PPC.UI.Navigation /// The object. /// if set to true [push to history]. /// - public Task NavigateForResult(TObject obj, bool pushToHistory = true) + public async Task NavigateForResult(TObject obj, bool pushToHistory = true) where TModule : IPPCModule { TaskCompletionSource source = new TaskCompletionSource(); - var fromVM = _currentVM; - Object toVM = null; - - - Action handler = null; + var fromVM = CurrentVM; - handler = (from, to) => + await NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (from, to) => { - if (toVM == null) - { - toVM = to; - if (toVM is INavigationResultProvider) - { - (toVM as INavigationResultProvider).OnNavigationObjectReceived(obj); - } - } - else + _awaitingVMResults.Add(new AwaitingVMResult() { - if (to == fromVM && from == toVM) + FromVM = fromVM as PPCViewModel, + ToVM = to as PPCViewModel, + Action = () => { - if (from is INavigationResultProvider) + if (to is INavigationResultProvider) { - source.SetResult((from as INavigationResultProvider).GetNavigationResult()); + source.SetResult((to as INavigationResultProvider).GetNavigationResult()); } } + }); - NavigationCycleCompleted -= handler; + if (to is INavigationResultProvider) + { + (to as INavigationResultProvider).OnNavigationObjectReceived(obj); } - }; - - NavigationCycleCompleted += handler; + }); - NavigateTo(typeof(TView).Name, pushToHistory); - - return source.Task; + return await source.Task; } /// @@ -320,25 +419,13 @@ namespace Tango.PPC.UI.Navigation /// public Task NavigateWithObject(TPass obj, bool pushToHistory = true) where TModule : IPPCModule { - TaskCompletionSource source = new TaskCompletionSource(); - - Action handler = null; - - handler = (from, to) => + return NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (fromVM, toVM) => { - if (to is INavigationObjectReceiver) + if (toVM is INavigationObjectReceiver) { - (to as INavigationObjectReceiver).OnNavigatedToWithObject(obj); + (toVM as INavigationObjectReceiver).OnNavigatedToWithObject(obj); } - - NavigationCycleCompleted -= handler; - }; - - NavigationCycleCompleted += handler; - - NavigateTo(typeof(TView).Name, pushToHistory); - - return source.Task; + }); } private Task NavigateTo(Type moduleType, bool pushToHistory = true, params String[] viewPath) @@ -361,6 +448,30 @@ namespace Tango.PPC.UI.Navigation get { return _navigationHistory.Count > 0; } } + private bool _isBackEnabled; + /// + /// Gets a value indicating whether the back should be enabled. + /// + public bool IsBackEnabled + { + get { return _isBackEnabled; } + set { _isBackEnabled = value; RaisePropertyChangedAuto(); } + } + + private bool _isNavigating; + /// + /// Gets or sets a value indicating whether the navigation system is currently navigating. + /// + public bool IsNavigating + { + get { return _isNavigating; } + set + { + _isNavigating = value; + RaisePropertyChangedAuto(); + } + } + /// /// Navigates to the previous view if is true. /// @@ -370,24 +481,34 @@ namespace Tango.PPC.UI.Navigation _navigating_back = true; - String first = _navigationHistory.Pop(); - _preventHistory = true; - - - if (await NavigateTo(first)) + if (_navigationHistory.Count > 0) { - RaisePropertyChanged(nameof(CanNavigateBack)); - _preventHistory = false; - _navigating_back = false; - return true; + String first = _navigationHistory.Pop(); + _preventHistory = true; + + if (await NavigateTo(first)) + { + RaisePropertyChanged(nameof(CanNavigateBack)); + _preventHistory = false; + _navigating_back = false; + return true; + } + else + { + _navigationHistory.Push(first); + _preventHistory = false; + _navigating_back = false; + RaisePropertyChanged(nameof(CanNavigateBack)); + return false; + } } else { - _navigationHistory.Push(first); + await NavigateTo(NavigationView.HomeModule); + RaisePropertyChanged(nameof(CanNavigateBack)); _preventHistory = false; _navigating_back = false; - RaisePropertyChanged(nameof(CanNavigateBack)); - return false; + return true; } } @@ -420,5 +541,48 @@ namespace Tango.PPC.UI.Navigation RaisePropertyChanged(nameof(CanNavigateBack)); } + + private void NotifyOnBeforeNavigated(object fromVM, object toVM) + { + if (fromVM == toVM) return; + + if (fromVM is PPCViewModel) + { + (fromVM as PPCViewModel)?.OnBeforeNavigatedFrom(); + } + + if (toVM is PPCViewModel) + { + (toVM as PPCViewModel)?.OnBeforeNavigatedTo(); + } + } + + private void NotifyOnNavigated(object fromVM, object toVM) + { + IsNavigating = false; + + if (fromVM == toVM) return; + + if (fromVM is PPCViewModel) + { + (fromVM as PPCViewModel)?.OnNavigatedFrom(); + } + + if (toVM is PPCViewModel) + { + (toVM as PPCViewModel)?.OnNavigatedTo(); + (toVM as PPCViewModel)?.OnNavigatedTo(fromVM as PPCViewModel); + } + } + + private void NotifyAwaitingVMResults(PPCViewModel fromVM, PPCViewModel toVM) + { + var awaiter = _awaitingVMResults.SingleOrDefault(x => x.FromVM == toVM && x.ToVM == fromVM); + if (awaiter != null) + { + _awaitingVMResults.Remove(awaiter); + awaiter.Action(); + } + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/DefaultNotificationProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/DefaultNotificationProvider.cs index 65337a892..e9de2538e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/DefaultNotificationProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/DefaultNotificationProvider.cs @@ -17,6 +17,8 @@ using Tango.Touch.Controls; using Tango.SharedUI; using System.Reflection; using Tango.Core.DI; +using System.ComponentModel; +using System.Windows.Data; namespace Tango.PPC.UI.Notifications { @@ -46,6 +48,16 @@ namespace Tango.PPC.UI.Notifications /// public ObservableCollection NotificationItems { get; private set; } + /// + /// Gets the application bar items. + /// + public ObservableCollection AppBarItems { get; private set; } + + /// + /// Gets the notification items view. + /// + public ICollectionView NotificationItemsView { get; private set; } + /// /// Gets the collection of taskbar items. /// @@ -58,6 +70,10 @@ namespace Tango.PPC.UI.Notifications { NotificationsVisible = true; NotificationItems = new ObservableCollection(); + + AppBarItems = new ObservableCollection(); + CollectionViewSource.GetDefaultView(AppBarItems).SortDescriptions.Add(new SortDescription(nameof(AppBarItem.Priority), ListSortDirection.Ascending)); + TaskBarItems = new ObservableCollection(); _pendingMessageBoxes = new ConcurrentQueue>(); _pendingDialogs = new ConcurrentQueue>(); @@ -66,6 +82,9 @@ namespace Tango.PPC.UI.Notifications PopNotificationCommand = new RelayCommand((x) => PopNotification(x)); NotificationItems.EnableCrossThreadOperations(); + + NotificationItemsView = CollectionViewSource.GetDefaultView(NotificationItems); + NotificationItemsView.SortDescriptions.Add(new SortDescription(nameof(NotificationItem.Priority), ListSortDirection.Descending)); } private MessageBoxVM _currentMessageBox; @@ -322,29 +341,33 @@ namespace Tango.PPC.UI.Notifications /// public async Task ShowDialog(T datacontext, FrameworkElement view) where T : DialogViewVM { - view.DataContext = datacontext; - - TangoIOC.Default.Inject(datacontext); + TaskCompletionSource source = new TaskCompletionSource(); - view.Loaded += (_, __) => + InvokeUI(() => { view.DataContext = datacontext; - datacontext.OnShow(); - }; - TaskCompletionSource source = new TaskCompletionSource(); + TangoIOC.Default.Inject(datacontext); - datacontext.Accepted += () => { OnDialogClosed(); source.SetResult(datacontext); }; - datacontext.Canceled += () => { OnDialogClosed(); source.SetResult(datacontext); }; + view.Loaded += (_, __) => + { + view.DataContext = datacontext; + datacontext.OnShow(); + }; - if (CurrentDialog == null) - { - CurrentDialog = view; - } - else - { - _pendingDialogs.Enqueue(new PendingNotification(new DialogAndView(datacontext, view), source)); - } + datacontext.Accepted += () => { OnDialogClosed(); source.SetResult(datacontext); }; + datacontext.Canceled += () => { OnDialogClosed(); source.SetResult(datacontext); }; + + if (CurrentDialog == null) + { + CurrentDialog = view; + } + else + { + _pendingDialogs.Enqueue(new PendingNotification(new DialogAndView(datacontext, view), source)); + } + + }); var result = await source.Task; return result as T; @@ -376,23 +399,31 @@ namespace Tango.PPC.UI.Notifications /// public Task ShowDialog(T datacontext) where T : DialogViewVM { - var callingAssembly = datacontext.GetType().Assembly; - String viewName = datacontext.GetType().FullName.Replace("VM", ""); - var viewType = callingAssembly.GetType(viewName); + TaskCompletionSource source = new TaskCompletionSource(); - if (viewType == null) + InvokeUI(async () => { - throw new NullReferenceException("View type for " + datacontext.GetType().Name + " could not be found!"); - } + var callingAssembly = datacontext.GetType().Assembly; + String viewName = datacontext.GetType().FullName.Replace("VM", ""); + var viewType = callingAssembly.GetType(viewName); - var view = Activator.CreateInstance(viewType) as FrameworkElement; + if (viewType == null) + { + throw new NullReferenceException("View type for " + datacontext.GetType().Name + " could not be found!"); + } - if (view == null) - { - throw new NullReferenceException("The view " + viewType.ToString() + " is not of type framework element."); - } + var view = Activator.CreateInstance(viewType) as FrameworkElement; - return ShowDialog(datacontext, view); + if (view == null) + { + throw new NullReferenceException("The view " + viewType.ToString() + " is not of type framework element."); + } + + T result = await ShowDialog(datacontext, view); + source.SetResult(result); + }); + + return source.Task; } /// @@ -404,7 +435,15 @@ namespace Tango.PPC.UI.Notifications /// public Task ShowDialog() where T : DialogViewVM { - return ShowDialog(Activator.CreateInstance()); + TaskCompletionSource source = new TaskCompletionSource(); + + InvokeUI(async () => + { + var result = await ShowDialog(Activator.CreateInstance()); + source.SetResult(result); + }); + + return source.Task; } /// @@ -442,22 +481,12 @@ namespace Tango.PPC.UI.Notifications /// public bool IsInGlobalBusyState { get; private set; } - private AppBarItem _currentAppBarItem; - /// - /// Gets the current application bar item. - /// - public AppBarItem CurrentAppBarItem - { - get { return _currentAppBarItem; } - set { _currentAppBarItem = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(HasAppBarItem)); } - } - /// /// Gets a value indicating whether this instance has application bar item. /// - public bool HasAppBarItem + public bool HasAppBarItems { - get { return CurrentAppBarItem != null; } + get { return AppBarItems.Count > 0; } } /// @@ -468,8 +497,9 @@ namespace Tango.PPC.UI.Notifications public AppBarItem PushAppBarItem(AppBarItem appBarItem) { LogManager.Log($"Pushing AppBarItem '{appBarItem.GetType().Name}'."); - CurrentAppBarItem = appBarItem; + AppBarItems.Add(appBarItem); appBarItem.RemoveAction = () => PopAppBarItem(appBarItem); + RaisePropertyChanged(nameof(HasAppBarItems)); return appBarItem; } @@ -478,9 +508,9 @@ namespace Tango.PPC.UI.Notifications /// /// /// - public AppBarItem PushAppBarItem() where T : AppBarItem + public T PushAppBarItem() where T : AppBarItem { - return PushAppBarItem(Activator.CreateInstance()); + return PushAppBarItem(Activator.CreateInstance()) as T; } /// @@ -489,8 +519,12 @@ namespace Tango.PPC.UI.Notifications /// The application bar item. public void PopAppBarItem(AppBarItem appBarItem) { - LogManager.Log($"Popping out AppBarItem '{appBarItem.GetType().Name}'."); - CurrentAppBarItem = null; + InvokeUI(() => + { + LogManager.Log($"Popping out AppBarItem '{appBarItem.GetType().Name}'."); + AppBarItems.Remove(appBarItem); + RaisePropertyChanged(nameof(HasAppBarItems)); + }); } /// diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItem.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItem.cs new file mode 100644 index 000000000..9e336f276 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItem.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common.Notifications; + +namespace Tango.PPC.UI.Notifications.NotificationItems +{ + /// + /// Represents a simple text message notification item which can be inserted into the application notifications panel. + /// + /// + public class UpdateAvailableNotificationItem : NotificationItem + { + /// + /// Initializes a new instance of the class. + /// + public UpdateAvailableNotificationItem() + { + CanClose = true; + } + + private String _version; + /// + /// Gets or sets the message. + /// + public String Version + { + get { return _version; } + set { _version = value; RaisePropertyChangedAuto(); } + } + + private bool _isDatabaseUpdate; + /// + /// Gets or sets a value indicating whether this instance is database update. + /// + public bool IsDatabaseUpdate + { + get { return _isDatabaseUpdate; } + set { _isDatabaseUpdate = value; RaisePropertyChangedAuto(); } + } + + /// + /// Gets or sets the view type. + /// + public override Type ViewType + { + get { return typeof(UpdateAvailableNotificationItemView); } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml new file mode 100644 index 000000000..1d4dd6fc7 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + Version + + is available! + Tap to start updating your system. + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml.cs new file mode 100644 index 000000000..791d40540 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Notifications/NotificationItems/UpdateAvailableNotificationItemView.xaml.cs @@ -0,0 +1,30 @@ +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.PPC.UI.Notifications.NotificationItems +{ + /// + /// Represents the view. + /// + /// + /// + public partial class UpdateAvailableNotificationItemView : UserControl + { + public UpdateAvailableNotificationItemView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs index c7351aa4a..83790a56f 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs @@ -32,6 +32,10 @@ using Tango.PPC.UI.Dialogs; using Tango.Core.Threading; using Tango.PPC.Common.Messages; using Tango.Core.ExtensionMethods; +using Tango.PPC.Common.Navigation; +using Tango.PPC.Common.Synchronization; +using Tango.Insights; +using System.Threading; namespace Tango.PPC.UI.PPCApplication { @@ -49,6 +53,7 @@ namespace Tango.PPC.UI.PPCApplication private IEventLogger _eventLogger; private IPPCModuleLoader _moduleLoader; private INotificationProvider _notificationProvider; + private IMachineDataSynchronizer _machineDataSynchronizer; private WatchDogServer _watchdogServer; private ObservablesContext _machineContext; private ActionTimer _screenLockTimer; @@ -58,6 +63,11 @@ namespace Tango.PPC.UI.PPCApplication /// public event EventHandler SystemRestartRequired; + /// + /// Occurs when the updater utility has failed to perform the last update. + /// + public event EventHandler UpdaterFailed; + /// /// Occurs when the application has started. /// @@ -93,10 +103,15 @@ namespace Tango.PPC.UI.PPCApplication /// public bool IsShuttingDown { get; private set; } + private bool _isInTechnicianMode; /// /// Gets a value indicating whether the application is in technician mode. /// - public bool IsInTechnicianMode { get; private set; } + public bool IsInTechnicianMode + { + get { return _isInTechnicianMode; } + set { _isInTechnicianMode = value; RaisePropertyChangedAuto(); } + } /// /// Gets the application version. @@ -125,6 +140,16 @@ namespace Tango.PPC.UI.PPCApplication /// public DateTime StartUpDate { get; private set; } + /// + /// Gets a value indicating whether an update has occurred before the application started. + /// + public bool IsAfterUpdate { get; private set; } + + /// + /// Gets a value indicating whether the updater utility has failed to perform the last update. + /// + public bool IsUpdateFailed { get; private set; } + private bool _isScreenLocked; /// /// Gets or sets a value indicating whether the screen is currently locked. @@ -135,16 +160,35 @@ namespace Tango.PPC.UI.PPCApplication set { _isScreenLocked = value; RaisePropertyChangedAuto(); } } + /// + /// Gets the firmware version. + /// + public Version FirmwareVersion + { + get + { + return Version.Parse(SettingsManager.Default.GetOrCreate().FirmwareVersion); + } + } + + /// + /// Gets or sets the application folder. + /// + public String StartPath { get; private set; } + /// /// Initializes a new instance of the class. /// - public DefaultPPCApplicationManager(IMachineProvider machineProvider, IDispatcherProvider dispatcherProvider, IEventLogger eventLogger, IPPCModuleLoader moduleLoader, INotificationProvider notificationProvider) + public DefaultPPCApplicationManager(IMachineProvider machineProvider, IDispatcherProvider dispatcherProvider, IEventLogger eventLogger, IPPCModuleLoader moduleLoader, INotificationProvider notificationProvider, IMachineDataSynchronizer machineDataSynchronizer) { + StartPath = AssemblyHelper.GetCurrentAssemblyFolder(); + _notificationProvider = notificationProvider; _machineProvider = machineProvider; _dispatcher = dispatcherProvider; _eventLogger = eventLogger; _moduleLoader = moduleLoader; + _machineDataSynchronizer = machineDataSynchronizer; if (!DesignMode) { @@ -210,11 +254,15 @@ namespace Tango.PPC.UI.PPCApplication { LogManager.Log("Application started with '-update_ok' startup arguments. The application has been successfully updated."); - if (settings.ApplicationState == ApplicationStates.PreSetup) + if (settings.ApplicationState == ApplicationStates.PreSetup || settings.ApplicationState == ApplicationStates.FactoryRestore) { isAfterSetup = true; LogManager.Log("System restart is required."); } + else + { + IsAfterUpdate = true; + } settings.ApplicationState = ApplicationStates.Ready; settings.Save(); @@ -226,13 +274,27 @@ namespace Tango.PPC.UI.PPCApplication } } + if (App.StartupArgs.Contains("-update_failed")) + { + LogManager.Log("Application started with '-update_failed' startup arguments. The updater utility has failed."); + + IsUpdateFailed = true; + + settings.ApplicationState = ApplicationStates.Ready; + settings.Save(); + UpdaterFailed?.Invoke(this, new EventArgs()); + return; + } + if (settings.ApplicationState == ApplicationStates.Ready) { LogManager.Log("Initializing ObservablesStaticCollections..."); ObservablesStaticCollections.Instance.Initialize(); LogManager.Log("Loading machine from database..."); _machineContext = ObservablesContext.CreateDefault(); - _machine = new MachineBuilder(_machineContext).SetFirst().WithVersion().WithSettings().WithOrganization().WithConfiguration().WithSpools().WithCats().Build(); + _machine = new MachineBuilder(_machineContext).SetFirst().WithVersion().WithOrganization().WithConfiguration().WithSpools().WithCats().Build(); + + } initialized = true; @@ -276,7 +338,6 @@ namespace Tango.PPC.UI.PPCApplication { LogManager.Log($"Raising {nameof(ApplicationStarted)} event..."); - _eventLogger.Log(EventTypes.APPLICATION_STARTED, "Application Started!"); ApplicationStarted?.Invoke(this, new EventArgs()); LogManager.Log("Invoking PPC view models OnApplicationStarted methods..."); @@ -290,6 +351,8 @@ namespace Tango.PPC.UI.PPCApplication } } + var internalModules = this.GetType().Assembly.GetTypes().Where(xx => typeof(PPCModuleBase).IsAssignableFrom(xx)).ToList(); + LogManager.Log("Waiting for IPPCModuleLoader instance injection..."); TangoIOC.Default.GetInstanceWhenAvailable((loader) => { @@ -304,12 +367,32 @@ namespace Tango.PPC.UI.PPCApplication { if (!Views.LayoutView.Instance.NavigationControl.Elements.ToList().Exists(m => m.GetType() == module.MainViewType)) { - LogManager.Log("Loading module view " + module.Name + "..."); - FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement; - SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name); - Views.LayoutView.Instance.NavigationControl.Elements.Add(view); + try + { + LogManager.Log("Loading module view " + module.Name + "..."); + FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement; + SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name); + Views.LayoutView.Instance.NavigationControl.Elements.Add(view); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error loading module view for module {module.Name}."); + } } } + + //Adding internal modules. + LogManager.Log("Loading internal modules..."); + foreach (var type in internalModules) + { + var module = Activator.CreateInstance(type) as IPPCModule; + LogManager.Log("Loading module view " + module.Name + "..."); + FrameworkElement view = Activator.CreateInstance(module.MainViewType) as FrameworkElement; + SharedUI.Controls.NavigationControl.SetNavigationName(view, module.Name); + Views.LayoutView.Instance.NavigationControl.Elements.Add(view); + _moduleLoader.AllModules.Add(module); + _moduleLoader.UserModules.Add(module); + } }); LogManager.Log($"{loader.UserModules.Count} modules loaded."); @@ -334,6 +417,9 @@ namespace Tango.PPC.UI.PPCApplication LogManager.Log("Initializing Machine Provider..."); _machineProvider.Init(_machine, _machineContext); + LogManager.Log("Starting Machine Data Synchronizer..."); + _machineDataSynchronizer.IsEnabled = true; + LogManager.Log("Applications initialization completed!"); LogManager.Log("Checking for un-notified PPC view models..."); @@ -350,6 +436,7 @@ namespace Tango.PPC.UI.PPCApplication _dispatcher.Invoke(() => { LogManager.Log($"Invoking {nameof(ApplicationReady)} event."); + _eventLogger.Log(EventTypes.APPLICATION_STARTED, "Application Started!"); ApplicationReady?.Invoke(this, new EventArgs()); LogManager.Log("Notifying view models about application ready..."); @@ -390,7 +477,7 @@ namespace Tango.PPC.UI.PPCApplication /// /// Shutdown the application. /// - public void ShutDown() + public async void ShutDown() { if (IsShuttingDown) return; @@ -408,13 +495,22 @@ namespace Tango.PPC.UI.PPCApplication } catch { } + try + { + await FinalizeApplication(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred on application shutdown finalization."); + } + Environment.Exit(0); } /// /// Restarts the application. /// - public void Restart() + public async void Restart() { if (IsShuttingDown) return; @@ -422,13 +518,28 @@ namespace Tango.PPC.UI.PPCApplication try { + _dispatcher.Invoke(() => + { + var nav = TangoIOC.Default.GetInstance(); + if (nav != null) + { + nav.NavigateTo(NavigationView.RestartingView); + } + }); + LogManager.Log("Restarting the application..."); + await Task.Delay(8000); + _watchdogServer.Dispose(); foreach (var vm in TangoIOC.Default.GetAllInstancesByBase()) { - vm.OnApplicationShuttingDown(); + try + { + vm.OnApplicationShuttingDown(); + } + catch { } } } catch { } @@ -442,6 +553,15 @@ namespace Tango.PPC.UI.PPCApplication } catch { } + try + { + await FinalizeApplication(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred on application shutdown finalization."); + } + Process.Start(Application.ResourceAssembly.Location); Environment.Exit(0); } @@ -449,25 +569,82 @@ namespace Tango.PPC.UI.PPCApplication /// /// Runs the updater utility and exits the application. /// - public void UpdateApplication(String updaterPath, String arguments) + public async void UpdateApplication(String updaterPath, String arguments) { if (IsShuttingDown) return; IsShuttingDown = true; + LogManager.Log("Restarting application for update..."); + try { - _watchdogServer.Dispose(); + LogManager.Log("Navigating to restart view..."); + _dispatcher.Invoke(() => + { + var nav = TangoIOC.Default.GetInstance(); + if (nav != null) + { + nav.NavigateTo(NavigationView.RestartingView); + } + }); + LogManager.Log("Waiting 2 seconds..."); + await Task.Delay(2000); + + try + { + LogManager.Log("Disposing watch dog..."); + _watchdogServer.Dispose(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error disposing watch dog."); + } + + LogManager.Log("Raising OnApplicationShutDown for all view models..."); foreach (var vm in TangoIOC.Default.GetAllInstancesByBase()) { - vm.OnApplicationShuttingDown(); + try + { + vm.OnApplicationShuttingDown(); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error on {vm.GetType().Name}.OnApplicationShutDown()."); + } } } catch { } + try + { + LogManager.Log("Saving application settings..."); + SettingsManager.Default.GetOrCreate().PreviousApplicationVersion = Version.ToString(); + SettingsManager.Default.Save(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving application settings."); + } + + try + { + await FinalizeApplication(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred on application shutdown finalization."); + } + LogManager.Log($"Executing '{updaterPath}' with arguments '{arguments}'..."); - Process.Start(updaterPath, arguments); + + Process p = new Process(); + p.StartInfo.FileName = updaterPath; + p.StartInfo.Arguments = arguments; + p.StartInfo.LoadUserProfile = true; + p.StartInfo.UseShellExecute = true; + p.Start(); LogManager.Log("Terminating application..."); Environment.Exit(0); @@ -546,5 +723,48 @@ namespace Tango.PPC.UI.PPCApplication { IsScreenLocked = true; } + + public void SetWindowState(WindowState state) + { + InvokeUI(() => + { + MainWindow.Instance.WindowState = state; + }); + } + + private Task FinalizeApplication() + { + LogManager.Log("Finalizing application..."); + + return LimitedTimeTask.StartNew(() => + { + try + { + LogManager.Log("Flushing machine events..."); + _eventLogger.Log(EventTypes.APPLICATION_TERMINATED, "User Interface Terminated."); + _eventLogger.FlushAll(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error flushing machine events."); + } + + try + { + LogManager.Log("Disposing insights manager (max 40 seconds to complete)..."); + Stopwatch watch = new Stopwatch(); + watch.Start(); + var frame = InsightsFrame.CreateEmpty(DateTime.UtcNow); + InsightsManager.Default.InsertFrame(frame); + InsightsManager.Default.Dispose(); + watch.Stop(); + LogManager.Log($"Insights manager disposed after {(int)watch.Elapsed.TotalSeconds} seconds."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error disposing insights manager."); + } + }, TimeSpan.FromSeconds(40)); + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Printing/DefaultPrintingManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Printing/DefaultPrintingManager.cs index 56ec2fa7e..1f2895f26 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Printing/DefaultPrintingManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Printing/DefaultPrintingManager.cs @@ -259,7 +259,11 @@ namespace Tango.PPC.UI.Printing { throw new InvalidOperationException("Error starting job. Color is out of range."); } - if (job.Segments.SelectMany(x => x.BrushStops).Any(x => x.BrushColorSpace == ColorSpaces.Catalog && x.ColorCatalogsItem == null)) + if (job.Segments.SelectMany(x => x.BrushStops).Any(x => x.IsLiquidVolumesOutOfRange)) + { + throw new InvalidOperationException("Error starting job. Total ink volume is out of range."); + } + if (job.Segments.SelectMany(x => x.BrushStops).Any(x => x.BrushColorSpace == ColorSpaces.Catalog && x.ColorCatalogsItem == null && !x.IsTransparent && !x.IsWhite)) { throw new InvalidOperationException("Error starting job. Please select a catalog color."); } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs index 02099e659..0540cfa9b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Properties/AssemblyInfo.cs @@ -8,4 +8,4 @@ using System.Windows; // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Tango PPC Application")] -[assembly: AssemblyVersion("1.0.50.0")] +[assembly: AssemblyVersion("1.2.9.0")] diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/RemoteActions/DefaultRemoteActionsService.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/RemoteActions/DefaultRemoteActionsService.cs new file mode 100644 index 000000000..1b8780f91 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/RemoteActions/DefaultRemoteActionsService.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.Core.Threading; +using Tango.Integration.ExternalBridge; +using Tango.PPC.Common.ExternalBridge; +using Tango.PPC.Common.RemoteActions; +using Tango.PPC.Common.Threading; +using Tango.PPC.Shared.RemoteActions; + +namespace Tango.PPC.UI.RemoteActions +{ + [TangoCreateWhenRegistered] + public class DefaultRemoteActionsService : IRemoteActionsService, IExternalBridgeRequestHandler + { + [TangoInject] + private IDispatcherProvider DispatcherProvider { get; set; } + + public DefaultRemoteActionsService(IPPCExternalBridgeService externalBridge) + { + externalBridge.RegisterRequestHandler(this); + } + + public void OnReceiverDisconnected(ExternalBridgeReceiver receiver) + { + //Do nothing. + } + + [ExternalBridgeRequestHandlerMethod(typeof(SimulateApplicationExceptionRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnSimulateApplicationExceptionRequest(SimulateApplicationExceptionRequest request, String token, ExternalBridgeReceiver receiver) + { + await receiver.SendGenericResponse(new SimulateApplicationExceptionResponse(), token); + + Thread.Sleep(500); + + DispatcherProvider.Invoke(() => + { + if (request.CrashApplication) + { + App.ExceptionTrapper.Disable(); + throw new OutOfMemoryException("This is a simulated exception to cause the application to crash."); + } + else + { + throw new ApplicationException("This is a simulated exception to cause an unhandled application error."); + } + }); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Resources/Colors.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Resources/Colors.xaml index f0e872285..d6cd842d5 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Resources/Colors.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Resources/Colors.xaml @@ -13,4 +13,6 @@ + + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj index c5045abf3..081d79f3e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj @@ -114,12 +114,23 @@ GlobalVersionInfo.cs + + + + PowerUpAppBarItemView.xaml + + + PowerOffAppBarItemView.xaml + WiFiAuthenticationView.xaml + + MachineStatusControl.xaml + @@ -129,6 +140,21 @@ InsufficientLiquidQuantityView.xaml + + SafetyLevelOperationsConfirmationView.xaml + + + + ThreadBreakView.xaml + + + + ThreadLoadingView.xaml + + + PowerUpView.xaml + + ScreenLockView.xaml @@ -138,21 +164,34 @@ + + + FirmwareUpgradeFromFileView.xaml + UpdateFromFileView.xaml + - + + + + + UpdateAvailableNotificationItemView.xaml + + + + @@ -161,13 +200,18 @@ + + ExternalBridgeView.xaml + + InternalModuleView.xaml + LayoutView.xaml @@ -177,6 +221,12 @@ LoadingErrorView.xaml + + PowerOffView.xaml + + + RestartingView.xaml + LoadingView.xaml @@ -198,15 +248,43 @@ RestartingSystemView.xaml + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + Designer MSBuild:Compile + + Designer + MSBuild:Compile + MSBuild:Compile Designer + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + Designer MSBuild:Compile @@ -218,6 +296,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -234,6 +316,10 @@ MainWindow.xaml Code + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -250,6 +336,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -262,6 +352,14 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -327,18 +425,59 @@ - - - Tango.ColorLib_v1.dll - PreserveNewest - - - Tango.ColorLib_v2.dll - PreserveNewest - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + SettingsSingleFileGenerator @@ -373,6 +512,10 @@ {4399af76-db52-4cfb-8020-6f85bdb29fd5} Tango.Explorer + + {4A55C185-3F8D-41B0-8815-C15F6213A14A} + Tango.Insights + {4206ac58-3b57-4699-8835-90bf6db01a61} Tango.Integration @@ -421,6 +564,10 @@ {6aa425c9-ea6a-4b01-aaed-5ff122e8b663} Tango.WiFi + + {bc2753f8-c0f7-48f5-a85c-149ec7a2f8c7} + Tango.PPC.BackupRestore + {8146fa0a-0725-4a1a-82e6-696c58f33a2b} Tango.PPC.BugReporting @@ -437,6 +584,10 @@ {91b70e9b-66a7-4873-ae10-400e71cf404f} Tango.PPC.MachineSettings + + {011470ac-6bd6-4366-b5f2-c82c065d4a84} + Tango.PPC.Maintenance + {04febb02-f782-4b96-b47d-f6902afa43be} Tango.PPC.Storage @@ -449,6 +600,40 @@ {0be74eee-22cb-4dba-b896-793b9e1a3ac0} Tango.PPC.Common + + {208c8bd8-72c6-4e3c-acaa-351091a2acc7} + Tango.PPC.Shared + + + + {E9528353-7D41-4AA8-BBAC-D65B7FE3A0D6} + Tango.ColorLib_v4 + false + Content + PreserveNewest + + + {A3A8ADA0-C150-4E30-A60D-11F291FDBF7A} + Tango.ColorLib_v3 + false + Content + PreserveNewest + + + {1A3FC7FB-403C-4B3D-B705-28FCE11317DD} + Tango.ColorLib_v2 + false + Content + PreserveNewest + + + {CF4C66B0-CD13-4D31-8133-339A01E7E6F2} + Tango.ColorLib_v1 + false + Content + PreserveNewest + + @@ -504,6 +689,7 @@ + @@ -560,6 +746,12 @@ RD /S /Q "$(TargetDir)nb-NO\" RD /S /Q "$(TargetDir)pt-BR\" RD /S /Q "$(TargetDir)roslyn\" +RD /S /Q "$(TargetDir)ProtoCompilers\" +RD /S /Q "$(TargetDir)Packages\ProtoCompilers\" +if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)x86\" +if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)x64\" + +if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)lib\" copy /Y "$(SolutionDir)Referenced Assemblies\mscoree.dll" "$(TargetDir)" copy /Y "$(SolutionDir)Referenced Assemblies\msvcp140d.dll" "$(TargetDir)" @@ -568,12 +760,17 @@ copy /Y "$(SolutionDir)Referenced Assemblies\vcruntime140.dll" "$(TargetDir)" copy /Y "$(SolutionDir)Referenced Assemblies\vcruntime140d.dll" "$(TargetDir)" copy /Y "$(SolutionDir)Referenced Assemblies\Microsoft.WITDataStore32.dll" "$(TargetDir)" -del "$(TargetDir)firmware_package.tfp" +if $(ConfigurationName) == Release del "$(TargetDir)firmware_package.tfp" + +if $(ConfigurationName) == Release del *.xml + +if $(ConfigurationName) == Release del WebRtc.NET.pdb -if $(ConfigurationName) == Release del *.xml +if $(ConfigurationName) == Debug copy /Y "$(TargetDir)Packages" "$(TargetDir)" - copy /Y "$(ProjectDir)Manifests\$(ConfigurationName).xml" "$(ProjectDir)app.manifest" + copy /Y "$(ProjectDir)Manifests\$(ConfigurationName).xml" "$(ProjectDir)app.manifest" + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ThreadLoading/DefaultThreadLoadingService.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ThreadLoading/DefaultThreadLoadingService.cs new file mode 100644 index 000000000..a6479da63 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ThreadLoading/DefaultThreadLoadingService.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Integration.Operation; +using Tango.PPC.Common.Connection; +using Tango.PPC.Common.Notifications; +using Tango.PPC.Common.Threading; +using Tango.PPC.Common.ThreadLoading; +using Tango.PPC.UI.Dialogs; + +namespace Tango.PPC.UI.ThreadLoading +{ + public class DefaultThreadLoadingService : IThreadLoadingService + { + private INotificationProvider _notificationsProvider; + private IMachineProvider _machineProvider; + private IDispatcherProvider _dispatcher; + private bool _dialogShown; + + public DefaultThreadLoadingService(INotificationProvider notificationsProvider, IMachineProvider machineProvider, IDispatcherProvider dispatcher) + { + _notificationsProvider = notificationsProvider; + _machineProvider = machineProvider; + _dispatcher = dispatcher; + _machineProvider.MachineOperator.ThreadLoadingStatusChanged += MachineOperator_ThreadLoadingStatusChanged; + } + + private void MachineOperator_ThreadLoadingStatusChanged(object sender, PMR.ThreadLoading.StartThreadLoadingResponse e) + { + if (!_dialogShown && e.State != PMR.ThreadLoading.ThreadLoadingState.None) + { + _dialogShown = true; + _dispatcher.Invoke(async () => + { + await _notificationsProvider.ShowDialog(new ThreadLoadingViewVM()); + _dialogShown = false; + }); + } + } + + public async void StartThreadLoadingWizard() + { + _dialogShown = true; + await _notificationsProvider.ShowDialog(new ThreadLoadingViewVM(true)); + _dialogShown = false; + } + + public async void StartThreadBreakWizard() + { + if (!_dialogShown) + { + _dialogShown = true; + var vm = await _notificationsProvider.ShowDialog(); + _dialogShown = false; + + if (vm.Result == ThreadBreakViewVM.ThreadBreakWizardResult.StartThreadLoading) + { + StartThreadLoadingWizard(); + } + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs index 67b5dc19b..222d3a1e8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs @@ -1,26 +1,41 @@ using System; +using System.Linq; using System.Windows; using Tango.Core.DI; using Tango.Integration.ExternalBridge; using Tango.Logging; using Tango.PPC.Common.Application; using Tango.PPC.Common.Authentication; +using Tango.PPC.Common.BackupRestore; using Tango.PPC.Common.Connection; using Tango.PPC.Common.Connectivity; +using Tango.PPC.Common.Console; +using Tango.PPC.Common.DataStore; using Tango.PPC.Common.Diagnostics; using Tango.PPC.Common.EventLogging; using Tango.PPC.Common.ExternalBridge; +using Tango.PPC.Common.FileSystem; using Tango.PPC.Common.HotSpot; +using Tango.PPC.Common.Insights; using Tango.PPC.Common.MachineSetup; using Tango.PPC.Common.MachineUpdate; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; using Tango.PPC.Common.Notifications; using Tango.PPC.Common.OS; +using Tango.PPC.Common.Performance; using Tango.PPC.Common.Printing; +using Tango.PPC.Common.RemoteActions; using Tango.PPC.Common.RemoteAssistance; +using Tango.PPC.Common.RemoteDesktop; +using Tango.PPC.Common.RemoteJob; +using Tango.PPC.Common.SQL; using Tango.PPC.Common.Storage; +using Tango.PPC.Common.Synchronization; +using Tango.PPC.Common.SystemInfo; using Tango.PPC.Common.Threading; +using Tango.PPC.Common.ThreadLoading; +using Tango.PPC.Common.UpdatePackages; using Tango.PPC.Common.UWF; using Tango.PPC.Common.Web; using Tango.PPC.UI.Authentication; @@ -30,7 +45,9 @@ using Tango.PPC.UI.Navigation; using Tango.PPC.UI.Notifications; using Tango.PPC.UI.PPCApplication; using Tango.PPC.UI.Printing; +using Tango.PPC.UI.RemoteActions; using Tango.PPC.UI.Threading; +using Tango.PPC.UI.ThreadLoading; using Tango.PPC.UI.ViewModels; using Tango.PPC.UI.Views; using Tango.PPC.UI.ViewsContracts; @@ -71,8 +88,30 @@ namespace Tango.PPC.UI TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); + + if (App.StartupArgs != null && App.StartupArgs.Contains("-webDebug")) + { + TangoIOC.Default.Register(new PPCWebClient("http://localhost:1111", null)); + } + else + { + TangoIOC.Default.Register(new PPCWebClient()); + } - TangoIOC.Default.Register(new PPCWebClient()); TangoIOC.Default.Register(new DefaultDispatcherProvider(Application.Current.Dispatcher)); TangoIOC.Default.Register(); TangoIOC.Default.Register(); @@ -80,11 +119,14 @@ namespace Tango.PPC.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); @@ -93,8 +135,17 @@ namespace Tango.PPC.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); - - //TangoIOC.Default.Register(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com", String.Empty, "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa")); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); @@ -107,6 +158,9 @@ namespace Tango.PPC.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.GetInstance().ContentRendered += (_, __) => @@ -212,5 +266,29 @@ namespace Tango.PPC.UI return TangoIOC.Default.GetInstance(); } } + + public static RestartingViewVM RestartingViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } + + public static InternalModuleViewVM InternalModuleViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } + + public static PowerOffViewVM PowerOffViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } } } \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs index f1127ebfe..f10e84d05 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs @@ -12,6 +12,7 @@ using Tango.PMR.Integration; using Tango.PPC.Common; using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Common.Navigation; +using Tango.PPC.UI.Dialogs; namespace Tango.PPC.UI.ViewModels { @@ -24,6 +25,8 @@ namespace Tango.PPC.UI.ViewModels { private bool _disconnecting; + private const int KEEP_SAFETY_AUTHENTICATION_MINUTES = 5; + #region Properties private ExternalBridgeClientConnectedEventArgs _connection; @@ -79,7 +82,7 @@ namespace Tango.PPC.UI.ViewModels LogManager.Log("Disconnecting current external bridge session."); _disconnecting = true; InvalidateRelayCommands(); - ExternalBridgeService.DisconnectSession(); + ExternalBridgeService.DisconnectFullControlSession(); } #endregion @@ -103,7 +106,7 @@ namespace Tango.PPC.UI.ViewModels public override void OnApplicationStarted() { ExternalBridgeService.ConnectionRequest += ExternalBridgeService_ConnectionRequest; - ExternalBridgeService.ClientDisconnected += ExternalBridgeService_ClientDisconnected; + ExternalBridgeService.FullControlSessionDisconnected += ExternalBridgeService_FullControlSessionDisconnected; } #endregion @@ -111,11 +114,11 @@ namespace Tango.PPC.UI.ViewModels #region Event Handlers /// - /// Handles the event. + /// Handles the event. /// /// The sender. /// The instance containing the event data. - private void ExternalBridgeService_ClientDisconnected(object sender, EventArgs e) + private void ExternalBridgeService_FullControlSessionDisconnected(object sender, EventArgs e) { if (IsVisible) { @@ -133,13 +136,14 @@ namespace Tango.PPC.UI.ViewModels /// /// The sender. /// The instance containing the event data. - private void ExternalBridgeService_ConnectionRequest(object sender, ExternalBridgeClientConnectedEventArgs e) + private async void ExternalBridgeService_ConnectionRequest(object sender, ExternalBridgeClientConnectedEventArgs e) { LogManager.Log($"External bridge connection request received.\n{e.ToJsonString()}"); if (!e.Request.Intent.RequiresPassword() || e.Request.Password == Settings.ExternalBridgePassword) { - e.Confirmed = true; + e.ApplicationInformation.Version = ApplicationManager.Version.ToString(); + e.ApplicationInformation.StartupDate = ApplicationManager.StartUpDate.ToUniversalTime().ToString(); Connection = e; @@ -150,6 +154,41 @@ namespace Tango.PPC.UI.ViewModels LogManager.Log($"External bridge connection user has been identified as {User.Contact.FullName}"); } + if (e.Request.RequireSafetyLevelOperations) + { + DateTime lastAuthenticationTime; + bool bypassSafetyConfirmation = false; + + if (ExternalBridgeReceiver.LastSafetyLevelContactsTimes.TryGetValue(e.Request.UserName, out lastAuthenticationTime)) + { + if (DateTime.Now < lastAuthenticationTime.AddMinutes(KEEP_SAFETY_AUTHENTICATION_MINUTES)) + { + bypassSafetyConfirmation = true; + e.Confirm(); + } + } + + if (!bypassSafetyConfirmation) + { + SafetyLevelOperationsConfirmationViewVM vm = new SafetyLevelOperationsConfirmationViewVM(e); + await NotificationProvider.ShowDialog(vm); + + if (vm.DialogResult) + { + e.Confirm(); + } + else + { + e.Decline("Safety level connection refused by the remote user."); + return; + } + } + } + else + { + e.Confirm(); + } + if (e.Request.Intent == ExternalBridgeLoginIntent.FullControl) { LogManager.Log("Navigating to external bridge view..."); @@ -161,6 +200,7 @@ namespace Tango.PPC.UI.ViewModels } else { + e.Decline("Connection password did not match the machine external bridge password."); LogManager.Log("Connection password did not match the machine external bridge password."); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/InternalModuleViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/InternalModuleViewVM.cs new file mode 100644 index 000000000..29e6417f4 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/InternalModuleViewVM.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common; + +namespace Tango.PPC.UI.ViewModels +{ + public class InternalModuleViewVM : PPCViewModel + { + public override void OnApplicationStarted() + { + + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs index 9e8a9fe34..a2baec8b8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LayoutViewVM.cs @@ -3,13 +3,19 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; using System.Windows.Threading; +using Tango.Core; using Tango.Core.Commands; using Tango.Core.DI; using Tango.Integration.Operation; +using Tango.PMR.IFS; using Tango.PPC.Common; +using Tango.PPC.Common.Connection; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; +using Tango.PPC.UI.Views; using Tango.PPC.UI.ViewsContracts; using Tango.SharedUI; @@ -22,6 +28,7 @@ namespace Tango.PPC.UI.ViewModels public class LayoutViewVM : PPCViewModel { private JobHandler _jobHandler; + private bool _resettingDevice; /// /// Gets or sets the module loader. @@ -29,6 +36,86 @@ namespace Tango.PPC.UI.ViewModels [TangoInject] public IPPCModuleLoader ModuleLoader { get; set; } + #region Classes + + public class CartridgeModel : ExtendedObject + { + private IMachineProvider _machineProvider; + + public CartridgeStatus Status { get; set; } + + public bool InProgress + { + get { return Status.State == CartridgeState.Filling || Status.State == CartridgeState.Emptying; } + } + + public String Message + { + get { return Status.Cartridge.Slot == PMR.Diagnostics.CartridgeSlot.Ink ? "Ink filling is in progress..." : "Waste emptying is in progress..."; } + } + + public Brush Brush + { + get + { + if (Status.Cartridge.Slot == PMR.Diagnostics.CartridgeSlot.Ink) + { + try + { + int index = Status.Cartridge.Index; + + var idsPack = _machineProvider.Machine.Configuration.NoneEmptyIdsPacks.FirstOrDefault(x => x.PackIndex == index); + + if (idsPack != null) + { + switch (idsPack.LiquidType.Type) + { + case BL.Enumerations.LiquidTypes.Cyan: + return Application.Current.Resources["TangoCyanInkBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Magenta: + return Application.Current.Resources["TangoMagentaInkBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Yellow: + return Application.Current.Resources["TangoYellowInkBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Black: + return Application.Current.Resources["TangoBlackInkBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Lubricant: + return Application.Current.Resources["TangoLubricantBrush"] as Brush; + case BL.Enumerations.LiquidTypes.Cleaner: + return Application.Current.Resources["TangoCleanerBrush"] as Brush; + case BL.Enumerations.LiquidTypes.TransparentInk: + return Application.Current.Resources["TangoTransparentInkBrush"] as Brush; + } + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error generating ink filling brush."); + } + + return Application.Current.Resources["TangoPrimaryAccentBrush"] as Brush; + } + else + { + return Application.Current.Resources["TangoWasteBrush"] as Brush; + } + } + } + + public CartridgeModel(IMachineProvider machineProvider) + { + _machineProvider = machineProvider; + Status = new CartridgeStatus(); + } + + public void Invalidate() + { + RaisePropertyChanged(nameof(InProgress)); + RaisePropertyChanged(nameof(Status)); + } + } + + #endregion + #region Properties private bool _isMenuOpened; @@ -72,6 +159,23 @@ namespace Tango.PPC.UI.ViewModels set { _isPowerOpened = value; RaisePropertyChangedAuto(); } } + private bool _isInkFillingOrWasteEmptying; + /// + /// Gets or sets a value indicating whether ink filling or waste emptying is active. + /// + public bool IsInkFillingOrWasteEmptying + { + get { return _isInkFillingOrWasteEmptying; } + set { _isInkFillingOrWasteEmptying = value; RaisePropertyChangedAuto(); } + } + + private List _cartridges; + public List Cartridges + { + get { return _cartridges; } + set { _cartridges = value; RaisePropertyChangedAuto(); } + } + #endregion #region Commands @@ -121,6 +225,21 @@ namespace Tango.PPC.UI.ViewModels /// public RelayCommand RestartApplicationCommand { get; set; } + /// + /// Gets or sets the power off command. + /// + public RelayCommand PowerOffCommand { get; set; } + + /// + /// Gets or sets the reset command. + /// + public RelayCommand ResetCommand { get; set; } + + /// + /// Gets or sets the stand by command. + /// + public RelayCommand StandByCommand { get; set; } + #endregion #region Constructors @@ -137,15 +256,13 @@ namespace Tango.PPC.UI.ViewModels StopPrintingCommand = new RelayCommand(StopPrinting); SignOutCommand = new RelayCommand(SignOut); - UpdateCommand = new RelayCommand(() => - { - NavigationManager.NavigateTo(NavigationView.MachineUpdateView); - TangoIOC.Default.GetInstance().CheckForUpdates(); - IsMenuOpened = false; - }); + UpdateCommand = new RelayCommand(UpdateMachine); PowerCommand = new RelayCommand(() => IsPowerOpened = true); RestartApplicationCommand = new RelayCommand(RestartApplication); + PowerOffCommand = new RelayCommand(PowerOffMachine, () => MachineProvider.MachineOperator.Status != MachineStatuses.Disconnected); + ResetCommand = new RelayCommand(ResetMachine, () => MachineProvider.MachineOperator.Status != MachineStatuses.Disconnected); + StandByCommand = new RelayCommand(StandBy, () => MachineProvider.MachineOperator.CanPrint); } #endregion @@ -239,6 +356,83 @@ namespace Tango.PPC.UI.ViewModels } } + /// + /// Powers off the machine. + /// + private async void PowerOffMachine() + { + IsMenuOpened = false; + + if (await NotificationProvider.ShowQuestion("Are you sure you wish to turn off the machine?")) + { + try + { + await MachineProvider.MachineOperator.PowerDown(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error triggering power down."); + await NotificationProvider.ShowError(ex.FlattenMessage()); + } + } + } + + /// + /// Resets the machine. + /// + private async void ResetMachine() + { + IsMenuOpened = false; + + if (!await NotificationProvider.ShowQuestion("Are you sure you want to reset the machine?")) return; + + try + { + _resettingDevice = true; + ResetCommand.RaiseCanExecuteChanged(); + await MachineProvider.MachineOperator.Reset(); + await NotificationProvider.ShowInfo("Machine was successfully restarted."); + } + catch (Exception ex) + { + await NotificationProvider.ShowError(ex.FlattenMessage()); + } + finally + { + _resettingDevice = false; + ResetCommand.RaiseCanExecuteChanged(); + } + } + + private async void StandBy() + { + IsMenuOpened = false; + + try + { + LogManager.Log("Executing stand-by command."); + await MachineProvider.MachineOperator.StandBy(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error switching to stand-by mode."); + await NotificationProvider.ShowError($"Error switching to stand-by mode.\n{ex.FlattenMessage()}"); + } + } + + private void UpdateMachine() + { + if (MachineProvider.MachineOperator.IsPrinting) + { + NotificationProvider.ShowInfo("Cannot perform a machine update while the machine is dyeing."); + return; + } + + NavigationManager.NavigateTo(NavigationView.MachineUpdateView); + TangoIOC.Default.GetInstance().CheckForUpdates(); + IsMenuOpened = false; + } + #endregion #region Override Methods @@ -250,6 +444,34 @@ namespace Tango.PPC.UI.ViewModels { base.OnApplicationStarted(); MachineProvider.MachineOperator.PrintingStarted += MachineOperator_PrintingStarted; + MachineProvider.MachineOperator.InkFillingStatusChanged += MachineOperator_InkFillingStatusChanged; + } + + private void MachineOperator_InkFillingStatusChanged(object sender, InkFillingStatusChangedEventArgs e) + { + if (Cartridges == null) + { + Cartridges = MachineProvider.MachineOperator.InkFillingStatus.CartridgesStatuses.Select(x => new CartridgeModel(MachineProvider) { Status = x }).ToList(); + } + else + { + foreach (var cartridgeStatus in e.Status.CartridgesStatuses) + { + var model = Cartridges.SingleOrDefault(x => x.Status == cartridgeStatus); + + if (model != null) + { + model.Status = cartridgeStatus; + } + } + } + + foreach (var cartridgeModel in Cartridges) + { + cartridgeModel.Invalidate(); + } + + IsInkFillingOrWasteEmptying = Cartridges.Any(x => x.Status.State == CartridgeState.Filling || x.Status.State == CartridgeState.Emptying); } /// @@ -260,6 +482,22 @@ namespace Tango.PPC.UI.ViewModels } + public override void OnApplicationReady() + { + base.OnApplicationReady(); + MachineProvider.MachineOperator.StatusChanged += MachineOperator_StatusChanged; + } + + private void MachineOperator_StatusChanged(object sender, MachineStatuses e) + { + InvokeUI(() => + { + PowerOffCommand.RaiseCanExecuteChanged(); + ResetCommand.RaiseCanExecuteChanged(); + StandByCommand.RaiseCanExecuteChanged(); + }); + } + #endregion #region Public Methods diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs index f926a0f4c..38dd569e1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoadingViewVM.cs @@ -74,37 +74,46 @@ namespace Tango.PPC.UI.ViewModels /// public async override void OnApplicationStarted() { - using (ObservablesContext db = ObservablesContext.CreateDefault()) - { - var machine = await db.Machines.FirstAsync(); + //We don't use authentication! - if (db.Users.Count() == 1 || machine.AutoLogin) - { - var user = await new UserBuilder(db).SetFirst().WithRolesAndPermissions().BuildAsync(); + //using (ObservablesContext db = ObservablesContext.CreateDefault()) + //{ + // var machine = await db.Machines.FirstAsync(); - if (!user.HasRole(Roles.PPCUser)) - { - var role = db.Roles.Single(x => x.Code == (int)Roles.PPCUser); - user.Roles.Add(role); - db.UsersRoles.Add(new BL.Entities.UsersRole() - { - User = user, - Role = role, - }); - await db.SaveChangesAsync(); - } + // if (db.Users.Count() == 1 || machine.AutoLogin) + // { + // var user = await new UserBuilder(db).SetFirst().WithRolesAndPermissions().BuildAsync(); - LogManager.Log($"Application started. Single user/Auto login detected ({user.Email}). Skipping LoginView..."); - await AuthenticationProvider.Login(user.Email, user.Password, false); - IsLoading = false; - } - else - { - LogManager.Log("Application started. Navigating to LoginView..."); - await NavigationManager.NavigateTo(NavigationView.LoginView); - IsLoading = false; - } - } + // if (!user.HasRole(Roles.PPCUser)) + // { + // var role = db.Roles.Single(x => x.Code == (int)Roles.PPCUser); + // user.Roles.Add(role); + // db.UsersRoles.Add(new BL.Entities.UsersRole() + // { + // User = user, + // Role = role, + // }); + // await db.SaveChangesAsync(); + // } + + // LogManager.Log($"Application started. Single user/Auto login detected ({user.Email}). Skipping LoginView..."); + // await AuthenticationProvider.Login(user.Email, user.Password, false); + // await Task.Delay(1000); + // IsLoading = false; + // } + // else + // { + // LogManager.Log("Application started. Navigating to LoginView..."); + // await NavigationManager.NavigateTo(NavigationView.LoginView); + // await Task.Delay(1000); + // IsLoading = false; + // } + //} + + LogManager.Log($"Application started with no authentication mode..."); + await AuthenticationProvider.Login(); + await Task.Delay(1000); + IsLoading = false; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs index aa9689ef3..ec316989f 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/LoginViewVM.cs @@ -92,7 +92,13 @@ namespace Tango.PPC.UI.ViewModels await Task.Delay(500); - if (AuthenticationProvider.CurrentUser != null && AuthenticationProvider.CurrentUser.HasPermission(Permissions.RunPPC)) + if (!AuthenticationProvider.AuthenticationRequired) + { + LogManager.Log("Application is ready! Navigating to home module..."); + await NavigationManager.NavigateTo(NavigationView.HomeModule); + IsLoading = false; + } + else if (AuthenticationProvider.CurrentUser != null && AuthenticationProvider.CurrentUser.HasPermission(Permissions.RunPPC)) { LogManager.Log("Application is ready! Navigating to home module..."); await NavigationManager.NavigateTo(NavigationView.HomeModule); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs index aca9dbcf7..ae31a64a1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineSetupViewVM.cs @@ -347,7 +347,10 @@ namespace Tango.PPC.UI.ViewModels try { - _ppcWebClient.Environment = DeploymentSlot; + if (!App.StartupArgs.Contains("-webDebug")) + { + _ppcWebClient.Environment = DeploymentSlot; + } await _operationSystemManager.ChangeTimeZone(SelectedTimeZone); _setup_result = await MachineSetupManager.Setup(SerialNumber); State = MachineSetupStates.Completed; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs index 01e67d3ce..5fe153ee9 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs @@ -1,22 +1,38 @@ using System; using System.Collections.Generic; +using System.Data.Entity; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using Tango.BL; +using Tango.Core; using Tango.Core.Commands; +using Tango.Core.ExtensionMethods; using Tango.Core.Helpers; +using Tango.Core.Threading; using Tango.Explorer; +using Tango.Integration.ExternalBridge; +using Tango.PMR.FirmwareUpgrade; using Tango.PPC.Common; +using Tango.PPC.Common.Application; +using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Common.MachineUpdate; +using Tango.PPC.Common.Navigation; +using Tango.PPC.Common.Notifications; +using Tango.PPC.Common.Publish; using Tango.PPC.Common.Web; +using Tango.PPC.Shared.RemoteUpgrade; using Tango.PPC.UI.Dialogs; +using Tango.PPC.UI.Notifications.NotificationItems; using Tango.PPC.UI.ViewsContracts; +using Tango.Transport; namespace Tango.PPC.UI.ViewModels { - public class MachineUpdateViewVM : PPCViewModel + public class MachineUpdateViewVM : PPCViewModel, IExternalBridgeRequestHandler { public enum MachineUpdateView { @@ -36,6 +52,7 @@ namespace Tango.PPC.UI.ViewModels private DbCompareResult _db_compare_result; private bool _isChecking; private CheckForUpdateResponse _checkUpdateResponse; + private UpdateAvailableNotificationItem _updateNotificationItem; #region Properties @@ -107,9 +124,10 @@ namespace Tango.PPC.UI.ViewModels #region Constructors - public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager) + public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager, IPPCExternalBridgeService externalBridge, IPPCApplicationManager applicationManager, INavigationManager navigationManager, INotificationProvider notificationProvider) { MachineUpdateManager = machineUpdateManager; + externalBridge.RegisterRequestHandler(this); CompleteCommand = new RelayCommand(CompleteUpdate); UpdateCommand = new RelayCommand(Update); @@ -125,6 +143,13 @@ namespace Tango.PPC.UI.ViewModels NavigationManager.NavigateTo(Common.Navigation.NavigationView.HomeModule); NavigateTo(MachineUpdateView.UpdateCheckView); }); + + machineUpdateManager.UpdateAvailable += MachineUpdateManager_UpdateAvailable; + + NavigationManager = navigationManager; + NotificationProvider = notificationProvider; + ApplicationManager = applicationManager; + ApplicationManager.UpdaterFailed += ApplicationManager_UpdaterFailed; } #endregion @@ -150,7 +175,28 @@ namespace Tango.PPC.UI.ViewModels return; } - var response = await MachineUpdateManager.CheckForUpdate(MachineProvider.Machine.SerialNumber); + var response = await MachineUpdateManager.CheckForUpdate(); + + try + { + if (response.UsedNotExistingRmlsGuids.Count > 0) + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + var arr = response.UsedNotExistingRmlsGuids.ToArray(); + var jobs = await db.Jobs.Where(x => arr.Contains(x.RmlGuid)).ToListAsync(); + FailedError = $"The following jobs must be removed or change thread type before the system can be updated:\n{String.Join("\n", jobs.Select(x => x.Name))}"; + _isChecking = false; + await NavigateTo(MachineUpdateView.UpdateFailedView); + return; + } + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error on used RML check procedure."); + } + _checkUpdateResponse = response; if (response.IsUpdateAvailable) @@ -158,9 +204,19 @@ namespace Tango.PPC.UI.ViewModels LatestVersion = response.Version; await NavigateTo(MachineUpdateView.UpdateAvailableView); } + else if (response.IsDatabaseUpdateAvailable) + { + IsDbUpdate = true; + _db_compare_result = new DbCompareResult() + { + RequiresUpdate = true, + UpdateDBResponse = response.UpdateDBResponse + }; + await NavigateTo(MachineUpdateView.UpdateAvailableView); + } else { - _db_compare_result = await MachineUpdateManager.UpdateDBCheck(MachineProvider.Machine.SerialNumber); + _db_compare_result = await MachineUpdateManager.UpdateDBCheck(); if (_db_compare_result.RequiresUpdate) { @@ -195,7 +251,7 @@ namespace Tango.PPC.UI.ViewModels try { - _update_result = await MachineUpdateManager.Update(MachineProvider.Machine.SerialNumber, _checkUpdateResponse.SetupFirmware, _checkUpdateResponse.SetupFPGA); + _update_result = await MachineUpdateManager.Update(_checkUpdateResponse.SetupFirmware, _checkUpdateResponse.SetupFPGA); LogManager.Log("Machine update completed."); await NavigateTo(MachineUpdateView.UpdateCompletedView); } @@ -213,7 +269,7 @@ namespace Tango.PPC.UI.ViewModels try { - await MachineUpdateManager.UpdateDB(_db_compare_result, MachineProvider.Machine.SerialNumber); + await MachineUpdateManager.UpdateDB(_db_compare_result); LogManager.Log("Database update completed."); await NavigateTo(MachineUpdateView.UpdateCompletedView); } @@ -234,15 +290,15 @@ namespace Tango.PPC.UI.ViewModels { LogManager.Log("Completing machine update..."); - if (!IsDbUpdate) + if (IsDbUpdate || !_update_result.RequiresBinariesUpdate) { - String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); - ApplicationManager.UpdateApplication(updater_exe, PathHelper.GetStartupPath()); + LogManager.Log("Restarting Application..."); + ApplicationManager.Restart(); } else { - LogManager.Log("Restarting Application..."); - ApplicationManager.Restart(); + String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); + ApplicationManager.UpdateApplication(updater_exe, PathHelper.GetStartupPath()); } } @@ -275,15 +331,100 @@ namespace Tango.PPC.UI.ViewModels base.OnApplicationReady(); StorageProvider.RegisterFileHandler(ExplorerFileDefinition.Update.Extension, HandleSoftwareUpdatePackageLoaded); + StorageProvider.RegisterFileHandler(ExplorerFileDefinition.Firmware.Extension, HandleFirmwareUpgradeLoaded); + + if (ApplicationManager.IsAfterUpdate) + { + RunPostUpdatePackages(); + } + else + { + MachineUpdateManager.EnableAutoCheckForUpdates = true; + } + } + + /// + /// Called when the navigation system has navigated to this VM view. + /// + public override void OnNavigatedTo() + { + base.OnNavigatedTo(); + + if (_updateNotificationItem != null) + { + _updateNotificationItem.Close(); + _updateNotificationItem = null; + } + } + + #endregion + + #region Post Update Packages + + private async void RunPostUpdatePackages() + { + await Task.Delay(1000); + + LogManager.Log("Application was loaded after an update. Checking for required post-update packages..."); + + bool required = false; + + try + { + required = await MachineUpdateManager.PostUpdatePackagesRequired(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error checking for post-update packages."); + } + + if (required) + { + LogManager.Log("Post-update packages found and needs to be installed. Navigating to machine update and running post-update packages..."); + await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + await NavigateTo(MachineUpdateView.UpdateProgressView); + try + { + var result = await MachineUpdateManager.RunPostUpdatePackages(); + + LogManager.Log("Post-update packages installed successfully."); + + await Task.Delay(2000); + + if (result.RestartRequired) + { + LogManager.Log("Restart required. Restarting..."); + ApplicationManager.Restart(); + } + else + { + await NavigationManager.NavigateTo(Common.Navigation.NavigationView.LayoutView); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while running post-update packages."); + } + } + else + { + LogManager.Log("No post-update packages installation required."); + } } #endregion #region Handle USB Update - private async void HandleSoftwareUpdatePackageLoaded(ExplorerFileItem fileItem) + private async void HandleSoftwareUpdatePackageLoaded(List fileItems) { - UpdatePackageFile packageFile = null; + var fileItem = fileItems.FirstOrDefault(); + + if (fileItem == null) return; + + PublishInfo packageFile = null; + + LogManager.Log("TUP file loaded from storage..."); try { @@ -291,43 +432,394 @@ namespace Tango.PPC.UI.ViewModels } catch (Exception ex) { - LogManager.Log(ex, $"Error loading update package file from {fileItem.Path}."); + LogManager.Log(ex, $"Error loading publish info from {fileItem.Path}."); await NotificationProvider.ShowError("An error occurred while trying to load the selected software update package. Please make sure the package is valid."); return; } - if (ApplicationManager.Version <= packageFile.Version) + UpdateFromFileViewVM vm = new UpdateFromFileViewVM(); + vm.PublishInfo = packageFile; + + LogManager.Log($"TUP publish info:\n{packageFile.ToJson()}"); + + LogManager.Log("Displaying TUP update dialog..."); + + await NotificationProvider.ShowDialog(vm); + + if (vm.DialogResult) + { + await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + await NavigateTo(MachineUpdateView.UpdateProgressView); + + LogManager.Log("Starting machine update from package..."); + + try + { + _update_result = await MachineUpdateManager.UpdateFromTUP(fileItem.Path, MachineProvider.Machine.SetupFirmware, MachineProvider.Machine.SetupFpga); + LogManager.Log("Machine update from package completed."); + await NavigateTo(MachineUpdateView.UpdateCompletedView); + } + catch (Exception ex) + { + LogManager.Log(ex, "Machine update from package failed."); + FailedError = ex.FlattenMessage(); + await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + } + } + } + + private async void HandleFirmwareUpgradeLoaded(List fileItems) + { + var fileItem = fileItems.FirstOrDefault(); + + if (fileItem == null) return; + + LogManager.Log("TFP file loaded from storage..."); + + VersionPackageDescriptor packageInfo; + FirmwareUpgradeFromFileViewVM vm = new FirmwareUpgradeFromFileViewVM(); + + try + { + using (FileStream st = File.OpenRead(fileItem.Path)) + { + packageInfo = await MachineProvider.MachineOperator.GetFirmwarePackageInfo(st); + } + + packageInfo.Validate(); + + vm.Version = packageInfo.GetMcuVersion().ToString(); + } + catch (Exception ex) { - await NotificationProvider.ShowError($"The selected update package (v{packageFile.Version.ToString()}) contains an older software version."); + LogManager.Log(ex, $"Error loading package info from {fileItem.Path}."); + await NotificationProvider.ShowError($"An error occurred while trying to load the selected firmware upgrade package.\n{ex.FlattenMessage()}"); return; } - UpdateFromFileViewVM vm = new UpdateFromFileViewVM(); - vm.Version = packageFile.Version.ToString(); + + LogManager.Log($"TFP publish info:\n{packageInfo.ToJsonString()}"); + + LogManager.Log("Displaying TFP update dialog..."); await NotificationProvider.ShowDialog(vm); if (vm.DialogResult) { await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); - await NavigateTo(MachineUpdateView.UpdateFromPackageView); + await NavigateTo(MachineUpdateView.UpdateProgressView); + + LogManager.Log("Starting firmware upgrade from package..."); + + try + { + await MachineUpdateManager.UpdateFromTFP(fileItem.Path); + LogManager.Log("Firmware upgrade from package completed."); + _update_result = new MachineUpdateResult() + { + RequiresBinariesUpdate = false, + }; + await NavigateTo(MachineUpdateView.UpdateCompletedView); + } + catch (Exception ex) + { + LogManager.Log(ex, "Firmware upgrade from package failed."); + FailedError = ex.FlattenMessage(); + await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + } + } + } + + #endregion + + #region Auto Check For Update + + private void MachineUpdateManager_UpdateAvailable(object sender, CheckForUpdateResponse e) + { + if (!IsVisible && _updateNotificationItem == null) + { + LogManager.Log($"New {(e.IsDatabaseUpdateAvailable ? "database updates" : "application version")} detected ({e.Version}). Pushing notification..."); + + InvokeUI(() => + { + _updateNotificationItem = new UpdateAvailableNotificationItem(); + _updateNotificationItem.Version = Version.Parse(e.Version).ToString(3); + _updateNotificationItem.IsDatabaseUpdate = e.IsDatabaseUpdateAvailable && !e.IsUpdateAvailable; + _updateNotificationItem.Pressed += (_, __) => + { + if (MachineProvider.MachineOperator.IsPrinting) + { + NotificationProvider.ShowInfo("Cannot perform a machine update while the machine is dyeing."); + return; + } + + _updateNotificationItem = null; + + if (!IsVisible) + { + LogManager.Log("Update available notification pressed. Navigating to update view..."); + NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + CheckForUpdates(); + } + }; + _updateNotificationItem.Closed += (_, __) => + { + _updateNotificationItem = null; + }; + NotificationProvider.PushNotification(_updateNotificationItem); + }); + } + } + + #endregion + + #region Updater Failed + + private void ApplicationManager_UpdaterFailed(object sender, EventArgs e) + { + InvokeUI(async () => + { + try + { + await NavigationManager.NavigateTo(NavigationView.MachineUpdateView); + await NavigateTo(MachineUpdateView.UpdateProgressView); + await MachineUpdateManager.RestoreLastDatabaseBackup(); + await Task.Delay(5000); + ApplicationManager.Restart(); + } + catch (Exception ex) + { + await NotificationProvider.ShowError($"Could not restore the application to its previous state.\n{ex.FlattenMessage()}"); + ApplicationManager.Restart(); + } + }); + } + + #endregion + + #region External Bridge Handler + + [ExternalBridgeRequestHandlerMethod(typeof(StartRemoteApplicationUpgradeRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnStartRemoteApplicationUpgradeRequest(StartRemoteApplicationUpgradeRequest request, String token, ExternalBridgeReceiver receiver) + { + await receiver.SendGenericResponse(new StartRemoteApplicationUpgradeResponse(), token); + + bool stopReporting = false; + + try + { + ThreadFactory.StartNew(async () => + { + while (!stopReporting) + { + if (MachineUpdateManager.Status != null) + { + try + { + await receiver.SendGenericResponse(new StartRemoteApplicationUpgradeResponse() + { + Progress = new TangoProgress() + { + Message = MachineUpdateManager.Status.Message, + IsIndeterminate = MachineUpdateManager.Status.IsIntermediate, + Maximum = MachineUpdateManager.Status.Total, + Value = MachineUpdateManager.Status.Progress + }, + }, token, new TransportResponseConfig() { Priority = QueuePriority.Low }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error sending remote upgrade progress."); + } + } + + Thread.Sleep(500); + } + }); + + InvokeUI(() => + { + NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + NavigateTo(MachineUpdateView.UpdateProgressView); + }); LogManager.Log("Starting machine update from package..."); try { - _update_result = await MachineUpdateManager.UpdateFromTUP(fileItem.Path); + _update_result = await MachineUpdateManager.UpdateFromTUP(request.RemoteTupFilePath, request.SetupFirmware, request.SetupFPGA); LogManager.Log("Machine update from package completed."); - await NavigateTo(MachineUpdateView.UpdateCompletedView); + stopReporting = true; + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateCompletedView); + }); } catch (Exception ex) { LogManager.Log(ex, "Machine update from package failed."); - await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + FailedError = ex.FlattenMessage(); + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + }); + + throw ex; + } + + await receiver.SendGenericResponse(new StartRemoteApplicationUpgradeResponse() + { + Progress = new TangoProgress("Completed", false, 100, 100), + }, token, new TransportResponseConfig() + { + Completed = true + }); + + try + { + File.Delete(request.RemoteTupFilePath); + } + catch { } + + await Task.Delay(2000); + + CompleteUpdate(); + } + catch (Exception ex) + { + stopReporting = true; + await receiver.SendErrorResponse(ex, token); + } + finally + { + stopReporting = true; + + try + { + File.Delete(request.RemoteTupFilePath); + } + catch { } + } + } + + [ExternalBridgeRequestHandlerMethod(typeof(StartRemoteFirmwareUpgradeRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnStartRemoteFirmwareUpgradeRequest(StartRemoteFirmwareUpgradeRequest request, String token, ExternalBridgeReceiver receiver) + { + await receiver.SendGenericResponse(new StartRemoteFirmwareUpgradeResponse(), token); + + bool stopReporting = false; + + try + { + ThreadFactory.StartNew(async () => + { + while (!stopReporting) + { + if (MachineUpdateManager.Status != null) + { + try + { + await receiver.SendGenericResponse(new StartRemoteFirmwareUpgradeResponse() + { + Progress = new TangoProgress() + { + Message = MachineUpdateManager.Status.Message, + IsIndeterminate = MachineUpdateManager.Status.IsIntermediate, + Maximum = MachineUpdateManager.Status.Total, + Value = MachineUpdateManager.Status.Progress + } + }, token, new TransportResponseConfig() { Priority = QueuePriority.Low }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error sending remote upgrade progress."); + } + } + + Thread.Sleep(500); + } + }); + + InvokeUI(() => + { + NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + NavigateTo(MachineUpdateView.UpdateProgressView); + }); + + LogManager.Log("Starting firmware upgrade from package..."); + + try + { + await MachineUpdateManager.UpdateFromTFP(request.RemoteTfpFilePath); + stopReporting = true; + LogManager.Log("Firmware upgrade from package completed."); + _update_result = new MachineUpdateResult() + { + RequiresBinariesUpdate = false, + }; + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateCompletedView); + }); + } + catch (Exception ex) + { + stopReporting = true; + + LogManager.Log(ex, "Firmware upgrade from package failed."); + FailedError = ex.FlattenMessage(); + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + }); + + throw ex; + } + + await receiver.SendGenericResponse(new StartRemoteFirmwareUpgradeResponse() + { + Progress = new TangoProgress("Completed", false, 100, 100), + }, token, new TransportResponseConfig() + { + Completed = true + }); + + try + { + File.Delete(request.RemoteTfpFilePath); } + catch { } + + await Task.Delay(2000); + + CompleteUpdate(); + } + catch (Exception ex) + { + stopReporting = true; + await receiver.SendErrorResponse(ex, token); + } + finally + { + stopReporting = true; + + try + { + File.Delete(request.RemoteTfpFilePath); + } + catch { } } } + public void OnReceiverDisconnected(ExternalBridgeReceiver receiver) + { + //Do Nothing. + } + #endregion } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs index 01a47539e..05fb610c8 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs @@ -4,6 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Threading; +using Tango.BL; +using Tango.BL.Builders; +using Tango.BL.Entities; using Tango.Core.DI; using Tango.Integration.ExternalBridge; using Tango.Integration.Operation; @@ -17,6 +20,8 @@ using Tango.PPC.Common.Notifications; using Tango.PPC.Common.WatchDog; using Tango.PPC.UI.Dialogs; using Tango.SharedUI; +using System.Data.Entity; +using Tango.PPC.UI.AppBarItems; namespace Tango.PPC.UI.ViewModels { @@ -27,6 +32,10 @@ namespace Tango.PPC.UI.ViewModels public class MainViewVM : PPCViewModel { private DispatcherTimer _date_timer; + private bool _isPowerUpDialogShown; + private bool _isThreadLoadingShown; + private PowerUpAppBarItem _powerUpAppBar; + private bool _started; private DateTime _currentDateTime; /// @@ -58,8 +67,53 @@ namespace Tango.PPC.UI.ViewModels { base.OnApplicationReady(); MachineProvider.MachineOperator.CartridgeValidationRequestReceived += MachineOperator_CartridgeValidationRequestReceived; + MachineProvider.MachineOperator.FirmwareStarted += MachineOperator_FirmwareStarted; + MachineProvider.MachineOperator.ThreadLoadingStatusChanged += MachineOperator_ThreadLoadingStatusChanged; + MachineProvider.MachineOperator.ThreadLoadingConfirmationRequired += MachineOperator_ThreadLoadingConfirmationRequired; + + MachineProvider.MachineOperator.PowerUpStarted += MachineOperator_PowerUpStarted; + MachineProvider.MachineOperator.PowerUpProgress += MachineOperator_PowerUpProgress; + MachineProvider.MachineOperator.PowerUpEnded += MachineOperator_PowerUpEnded; + } + + #region Power Up + + private void MachineOperator_PowerUpEnded(object sender, EventArgs e) + { + _started = false; + _powerUpAppBar?.Close(); + _powerUpAppBar = null; + } + + private void MachineOperator_PowerUpProgress(object sender, PMR.Power.StartPowerUpResponse status) + { + if (_powerUpAppBar != null) + { + _powerUpAppBar.Status = status; + } + } + + private void MachineOperator_PowerUpStarted(object sender, PMR.Power.StartPowerUpResponse e) + { + _started = true; + + InvokeUI(() => + { + if (_powerUpAppBar != null) + { + _powerUpAppBar.Close(); + } + + if (_started) + { + _powerUpAppBar = NotificationProvider.PushAppBarItem(); + _powerUpAppBar.Priority = AppBarPriority.Low; + } + }); } + #endregion + #region Event Handlers /// @@ -92,6 +146,106 @@ namespace Tango.PPC.UI.ViewModels }); } + private async void MachineOperator_FirmwareStarted(object sender, EventArgs e) + { + if (_isPowerUpDialogShown) + { + LogManager.Log("Power up detected but power up dialog is already shown. Skipping..."); + return; + } + + LogManager.Log("Power up detected, showing power up screen..."); + + if (!Settings.DisplayPowerUpScreen) + { + LogManager.Log("Power up screen disabled. skipping..."); + return; + } + + PowerUpViewVM vm; + + try + { + LogManager.Log("Loading site rmls..."); + + List rmls = new List(); + + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + rmls = await new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).BuildListAsync(); + } + + var selectedRml = rmls.SingleOrDefault(x => x.Guid == Settings.LoadedRmlGuid); + + vm = new PowerUpViewVM(); + vm.Rmls = rmls; + vm.SelectedRml = selectedRml != null ? selectedRml : rmls.FirstOrDefault(); + vm.IsSelectedRml = selectedRml != null; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error initializing power up screen."); + return; + } + + InvokeUI(async () => + { + _isPowerUpDialogShown = true; + await NotificationProvider.ShowDialog(vm); + _isPowerUpDialogShown = false; + + await Task.Factory.StartNew(() => + { + LogManager.Log("Power up screen closed."); + + try + { + using (ObservablesContext db = ObservablesContext.CreateDefault()) + { + List processTables = new List(); + + if (vm.IsSelectedRml) + { + LogManager.Log($"Selected rml '{vm.SelectedRml.Name}'..."); + processTables = new RmlBuilder(db).Set(vm.SelectedRml.Guid).WithActiveParametersGroup().Build().GetActiveProcessGroup().ProcessParametersTables.ToList(); + } + else + { + LogManager.Log("Selected minimal temperature..."); + var rmlsToAvg = new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).WithActiveParametersGroup().Build(); + processTables = rmlsToAvg.Select(x => x.GetActiveProcessGroup()).SelectMany(x => x.ProcessParametersTables).ToList(); + } + + var processToLoad = processTables.OrderBy(x => x.GetAverageTemperature()).First(); + + LogManager.Log($"Selected process parameters:\nRML: {processToLoad.ProcessParametersTablesGroup.Rml.Name}\nGroup: {processToLoad.ProcessParametersTablesGroup.Name}\nProcess Table: {processToLoad.Name}"); + LogManager.Log("Uploading process parameters..."); + var r = MachineProvider.MachineOperator.UploadProcessParameters(processToLoad).Result; + + Settings.LoadedRmlGuid = vm.IsSelectedRml ? vm.SelectedRml.Guid : null; + Settings.Save(); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to get and upload the proper process parameters after power screen closed."); + } + }); + }); + } + + private void MachineOperator_ThreadLoadingStatusChanged(object sender, PMR.ThreadLoading.StartThreadLoadingResponse e) + { + //if (e.State == PMR.ThreadLoading.ThreadLoadingState.Preparing) + //{ + // DisplayThreadLoading(); + //} + } + + private void MachineOperator_ThreadLoadingConfirmationRequired(object sender, ThreadLoadingConfirmationRequiredEventArgs e) + { +// DisplayThreadLoading(e); + } #endregion } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/PowerOffViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/PowerOffViewVM.cs new file mode 100644 index 000000000..e3ab7d111 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/PowerOffViewVM.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.Integration.Operation; +using Tango.PMR.Power; +using Tango.PPC.Common; +using Tango.PPC.UI.AppBarItems; +using Tango.PPC.UI.Views; + +namespace Tango.PPC.UI.ViewModels +{ + public class PowerOffViewVM : PPCViewModel + { + private PowerDownHandler _handler; + private PowerOffAppBarItem _appBarItem; + private int _abortTries; + + private StartPowerDownResponse _status; + public StartPowerDownResponse Status + { + get { return _status; } + set { _status = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand AbortCommand { get; set; } + + public PowerOffViewVM() + { + _appBarItem = new PowerOffAppBarItem(); + _appBarItem.Pressed += (x, e) => + { + NavigationManager.NavigateTo(nameof(PowerOffView)); + }; + AbortCommand = new RelayCommand(AbortPowerOff); + } + + public override void OnApplicationStarted() + { + + } + + public override void OnApplicationReady() + { + base.OnApplicationReady(); + MachineProvider.MachineOperator.PowerDownStarted += MachineOperator_PowerDownStarted; + } + + private void MachineOperator_PowerDownStarted(object sender, PowerDownStartedEventArgs e) + { + _abortTries = 0; + _handler = e.Handler; + + _handler.StatusChanged += OnStatusChanged; + _handler.Failed += OnFailed; + _handler.Completed += OnCompleted; + + InvokeUI(async () => + { + await NavigationManager.NavigateTo(nameof(PowerOffView)); + NotificationProvider.PushAppBarItem(_appBarItem); + }); + } + + private void OnStatusChanged(object sender, PowerDownStatusChangedEventArgs e) + { + Status = e.Status; + _appBarItem.Status = Status; + } + + private void OnCompleted(object sender, EventArgs e) + { + InvokeUI(async () => + { + if (IsVisible) + { + await NavigationManager.NavigateBack(); + } + + NotificationProvider.PopAppBarItem(_appBarItem); + }); + } + + private void OnFailed(object sender, Exception ex) + { + InvokeUI(async () => + { + await NotificationProvider.ShowError($"An error occurred while powering off the machine.\n{ex.FlattenMessage()}"); + + if (IsVisible) + { + await NavigationManager.NavigateBack(); + } + + NotificationProvider.PopAppBarItem(_appBarItem); + }); + } + + private async void AbortPowerOff() + { + try + { + NotificationProvider.SetGlobalBusyMessage("Aborting machine power off..."); + await _handler.Abort(); + await NavigationManager.NavigateBack(); + NotificationProvider.PopAppBarItem(_appBarItem); + } + catch (Exception ex) + { + _abortTries++; + LogManager.Log(ex, "Power down abort error."); + NotificationProvider.ReleaseGlobalBusyMessage(); + await NotificationProvider.ShowError($"An error occurred while trying to abort the power off sequence.\n{ex.FlattenMessage()}"); + + if (_abortTries > 2) + { + if (IsVisible) + { + await NavigationManager.NavigateBack(); + } + + NotificationProvider.PopAppBarItem(_appBarItem); + } + } + finally + { + NotificationProvider.ReleaseGlobalBusyMessage(); + } + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/RestartingViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/RestartingViewVM.cs new file mode 100644 index 000000000..46111031b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/RestartingViewVM.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Common; + +namespace Tango.PPC.UI.ViewModels +{ + public class RestartingViewVM : PPCViewModel + { + public override void OnApplicationStarted() + { + + } + + public override void OnNavigatedTo() + { + base.OnNavigatedTo(); + } + + public override void OnNavigatedFrom() + { + base.OnNavigatedFrom(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/EmergencyView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/EmergencyView.xaml index dfc70e602..f2b018bfa 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/EmergencyView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/EmergencyView.xaml @@ -9,12 +9,18 @@ xmlns:local="clr-namespace:Tango.PPC.UI.Views" mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:EmergencyViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.EmergencyViewVM}"> - + - - - Emergency Switch Activated - Please release the emergency switch to exit this screen. + + + EMERGENCY PUSH BUTTON PRESSED + How to handle: + + 1. Verify that it is safe to restart the system. + 2. Release the emergency button. + 3. Press the power button to power up the system. + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml index d83128007..fddd15fe7 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/ExternalBridgeView.xaml @@ -7,18 +7,23 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:Tango.PPC.UI.ViewModels" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:localControls="clr-namespace:Tango.PPC.UI.Controls" xmlns:local="clr-namespace:Tango.PPC.UI.Views" mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:ExternalBridgeViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.ExternalBridgeViewVM}" Background="{StaticResource TangoPrimaryBackgroundBrush}"> - - - + + + + + + + + - - + @@ -302,8 +287,21 @@ - - + + + + + + + + + + + + + + + @@ -330,6 +328,35 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs index 883d3f893..b87f14b89 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LayoutView.xaml.cs @@ -30,7 +30,7 @@ namespace Tango.PPC.UI.Views { public static LayoutView Instance { get; private set; } private LayoutViewVM _vm; - private DispatcherTimer _timer; + private System.Timers.Timer _timer; public LayoutView() { @@ -39,9 +39,9 @@ namespace Tango.PPC.UI.Views Loaded += (_, __) => _vm = DataContext as LayoutViewVM; techPressElement.RegisterForPreviewMouseOrTouchDown(OnMouseOrTouchDown); techPressElement.RegisterForPreviewMouseOrTouchUp(OnMouseOrTouchUp); - _timer = new DispatcherTimer(); - _timer.Interval = TimeSpan.FromSeconds(10); - _timer.Tick += _timer_Tick; + _timer = new System.Timers.Timer(); + _timer.Interval = TimeSpan.FromSeconds(10).TotalMilliseconds; + _timer.Elapsed += _timer_Elapsed; this.PreviewMouseUp += LayoutView_PreviewMouseUp; } @@ -51,10 +51,14 @@ namespace Tango.PPC.UI.Views _vm.ApplicationManager.ResetScreenLockTimer(); } - private void _timer_Tick(object sender, EventArgs e) + private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { _timer.Stop(); - _vm.ToggleTechnicianMode(); + + Dispatcher.BeginInvoke(new Action(() => + { + _vm.ToggleTechnicianMode(); + })); } private void OnMouseOrTouchDown(object sender, MouseOrTouchEventArgs e) diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml index 79d9cd54b..a917695af 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml @@ -10,9 +10,9 @@ xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" xmlns:local="clr-namespace:Tango.PPC.UI.Views" mc:Ignorable="d" - d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:LoadingViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LoadingView}"> + d:DesignHeight="1280" d:DesignWidth="800" Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:LoadingViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LoadingView}"> - + - - - + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml index 9437caac9..40b296d1e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml @@ -25,7 +25,7 @@ - + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml index fba8a599d..beb09be0d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml @@ -194,8 +194,9 @@ CLOSE - - An error occurred while trying to update the machine. + + Update Failed + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs index f63899932..13a605774 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -37,7 +38,10 @@ namespace Tango.PPC.UI.Views navigationControl.NavigateTo(view.ToString(), () => { - source.SetResult(new object()); + if (!source.Task.IsCompleted) + { + source.SetResult(new object()); + } }); return source.Task; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml index 6d6d57526..2e36347a3 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MainView.xaml @@ -7,6 +7,7 @@ xmlns:commonControls="clr-namespace:Tango.PPC.Common.Controls;assembly=Tango.PPC.Common" xmlns:vm="clr-namespace:Tango.PPC.UI.ViewModels" xmlns:global="clr-namespace:Tango.PPC.UI" + xmlns:operations="clr-namespace:Tango.Integration.Operation;assembly=Tango.Integration" xmlns:local="clr-namespace:Tango.PPC.UI.Views" xmlns:notifications="clr-namespace:Tango.PPC.UI.Notifications" xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" @@ -46,6 +47,21 @@ + + + + + + @@ -53,7 +69,7 @@ + + @@ -89,6 +144,7 @@ + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml new file mode 100644 index 000000000..22952a827 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml @@ -0,0 +1,20 @@ + + + + + Machine is turning Off + Do not unplug machine while turning off + ABORT + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml.cs new file mode 100644 index 000000000..ead34ae12 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.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.PPC.UI.Views +{ + /// + /// Interaction logic for LoadingView.xaml + /// + public partial class PowerOffView : UserControl + { + public PowerOffView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml index 996b1788d..dd4d2f5d5 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml @@ -10,17 +10,37 @@ mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:RestartingSystemViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.RestartingSystemViewVM}" Background="{StaticResource TangoPrimaryBackgroundBrush}"> - - - - - Setup completed. - - - - Restarting the system for the last time... - + + + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml new file mode 100644 index 000000000..41017f629 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml @@ -0,0 +1,52 @@ + + + + + + + + + + v + + + + + + + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.xaml.cs new file mode 100644 index 000000000..fabd7b47b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingView.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.PPC.UI.Views +{ + /// + /// Interaction logic for LoadingView.xaml + /// + public partial class RestartingView : UserControl + { + public RestartingView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest index efc5f8179..d72e75011 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest @@ -16,7 +16,7 @@ Remove this element if your application requires this virtualization for backwards compatibility. --> - + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/firmware_package.tfp b/Software/Visual_Studio/PPC/Tango.PPC.UI/firmware_package.tfp new file mode 100644 index 000000000..bc33e385a Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/firmware_package.tfp differ -- cgit v1.3.1