From 03bc9bd370929884f98ee9488146646d44911efd Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Wed, 5 Aug 2020 22:18:14 +0300 Subject: Improved PPC Publisher for Firmware version display and validation. --- .../Web/Tango.MachineService/Controllers/PPCController.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 10af2f725..22feb29c1 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -788,10 +788,13 @@ namespace Tango.MachineService.Controllers return new LatestVersionResponse() { Version = "0.0.0.0", + FirmwareVersion = "0.0.0.0" }; } - response.Version = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault().Version; + var latestTangoVersion = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + response.Version = latestTangoVersion.Version; + response.FirmwareVersion = latestTangoVersion.FirmwareVersion; } return response; -- cgit v1.3.1 From f809df07060dc3a27167f68027eb03bdbc89221a Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sat, 15 Aug 2020 19:13:10 +0300 Subject: File Associations DDE!! --- .../FSE/File Associations/procedure_dde.ico | Bin 0 -> 107997 bytes .../FSE/File Associations/procedure_dde.png | Bin 0 -> 6350 bytes .../Graphics/FSE/File Associations/tdp_dde.ico | Bin 0 -> 109508 bytes .../Graphics/FSE/File Associations/tdp_dde.png | Bin 0 -> 7337 bytes .../Graphics/FSE/File Associations/tfp_dde.ico | Bin 0 -> 105372 bytes .../Graphics/FSE/File Associations/tfp_dde.png | Bin 0 -> 4111 bytes .../Graphics/FSE/File Associations/tup_dde.ico | Bin 0 -> 106375 bytes .../Graphics/FSE/File Associations/tup_dde.png | Bin 0 -> 5048 bytes .../Advanced Installer Projects/FSE Installer.aip | 20 ++- .../ViewModels/DiagnosticsViewVM.cs | 35 ++++++ .../Help/proc-doc.chm | Bin 206257 -> 212099 bytes .../Tango.FSE.Procedures.Documentation.shfbproj | 1 + .../Navigation/RunProcedureNavigationObject.cs | 1 + .../ViewModels/ProcedureDesignerViewVM.cs | 39 +++++- .../ViewModels/ProcedureRunnerViewVM.cs | 60 ++++++--- .../ViewModels/FirmwareUpgradeGeneratedViewVM.cs | 40 +++++- .../Views/FirmwareUpgradeView.xaml | 2 +- .../FSEApplication/IFSEApplicationManager.cs | 5 + .../FSE/Tango.FSE.Common/FSESettings.cs | 6 + .../FSE/Tango.FSE.Common/FSEViewModel.cs | 7 ++ .../FileAssociation/FileAssociationPackage.cs | 1 + .../FileAssociation/IFileAssociationProvider.cs | 3 +- .../Navigation/INavigationManager.cs | 5 +- .../Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs | 46 +++++-- .../FSEApplication/DefaultFSEApplicationManager.cs | 11 ++ .../DefaultFileAssociationHandler.cs | 24 ---- .../DefaultFileAssociationProvider.cs | 136 +++++++++++++++++++++ .../Navigation/DefaultNavigationManager.cs | 10 +- .../FSE/Tango.FSE.UI/Tango.FSE.UI.csproj | 5 +- .../FSE/Tango.FSE.UI/ViewModelLocator.cs | 4 + .../FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs | 8 ++ .../Visual_Studio/FSE/Tango.FSE.UI/packages.config | 1 + .../Controllers/FSEController.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- 34 files changed, 406 insertions(+), 68 deletions(-) create mode 100644 Software/Graphics/FSE/File Associations/procedure_dde.ico create mode 100644 Software/Graphics/FSE/File Associations/procedure_dde.png create mode 100644 Software/Graphics/FSE/File Associations/tdp_dde.ico create mode 100644 Software/Graphics/FSE/File Associations/tdp_dde.png create mode 100644 Software/Graphics/FSE/File Associations/tfp_dde.ico create mode 100644 Software/Graphics/FSE/File Associations/tfp_dde.png create mode 100644 Software/Graphics/FSE/File Associations/tup_dde.ico create mode 100644 Software/Graphics/FSE/File Associations/tup_dde.png delete mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationHandler.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers') diff --git a/Software/Graphics/FSE/File Associations/procedure_dde.ico b/Software/Graphics/FSE/File Associations/procedure_dde.ico new file mode 100644 index 000000000..7df42ce47 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/procedure_dde.ico differ diff --git a/Software/Graphics/FSE/File Associations/procedure_dde.png b/Software/Graphics/FSE/File Associations/procedure_dde.png new file mode 100644 index 000000000..1e92440d6 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/procedure_dde.png differ diff --git a/Software/Graphics/FSE/File Associations/tdp_dde.ico b/Software/Graphics/FSE/File Associations/tdp_dde.ico new file mode 100644 index 000000000..a81e68d65 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tdp_dde.ico differ diff --git a/Software/Graphics/FSE/File Associations/tdp_dde.png b/Software/Graphics/FSE/File Associations/tdp_dde.png new file mode 100644 index 000000000..9ba449028 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tdp_dde.png differ diff --git a/Software/Graphics/FSE/File Associations/tfp_dde.ico b/Software/Graphics/FSE/File Associations/tfp_dde.ico new file mode 100644 index 000000000..27ce70914 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tfp_dde.ico differ diff --git a/Software/Graphics/FSE/File Associations/tfp_dde.png b/Software/Graphics/FSE/File Associations/tfp_dde.png new file mode 100644 index 000000000..0577cfb13 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tfp_dde.png differ diff --git a/Software/Graphics/FSE/File Associations/tup_dde.ico b/Software/Graphics/FSE/File Associations/tup_dde.ico new file mode 100644 index 000000000..013e33ba5 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tup_dde.ico differ diff --git a/Software/Graphics/FSE/File Associations/tup_dde.png b/Software/Graphics/FSE/File Associations/tup_dde.png new file mode 100644 index 000000000..9c6374f87 Binary files /dev/null and b/Software/Graphics/FSE/File Associations/tup_dde.png differ diff --git a/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip b/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip index 4d7250d8e..901fd1a05 100644 --- a/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip +++ b/Software/Visual_Studio/Advanced Installer Projects/FSE Installer.aip @@ -310,6 +310,7 @@ + @@ -666,6 +667,7 @@ + @@ -810,6 +812,9 @@ + + + @@ -1078,11 +1083,15 @@ + - + + + + @@ -1139,7 +1148,10 @@ - + + + + @@ -1166,6 +1178,10 @@ + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs index ac9279ab8..8a89fbc8f 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Diagnostics/ViewModels/DiagnosticsViewVM.cs @@ -15,8 +15,10 @@ using Tango.BL.Enumerations; using Tango.Core.Commands; using Tango.FSE.Common; using Tango.FSE.Common.Diagnostics; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Notifications; using Tango.FSE.Diagnostics.Project; +using Tango.FSE.Diagnostics.Views; using Tango.PMR.Diagnostics; namespace Tango.FSE.Diagnostics.ViewModels @@ -403,6 +405,8 @@ namespace Tango.FSE.Diagnostics.ViewModels { base.OnApplicationStarted(); DiagnosticsProvider.FrameReceived += DiagnosticsProvider_FrameReceived; + + FileAssociationProvider.RegisterFileAssociationHandler("diagnostics", HandleDiagnosticsFileAssociation); } public async override void OnApplicationReady() @@ -781,5 +785,36 @@ namespace Tango.FSE.Diagnostics.ViewModels } #endregion + + #region File Association + + private async void HandleDiagnosticsFileAssociation(FileAssociationPackage package) + { + if (!CurrentUser.HasPermission(Permissions.FSE_EditDiagnosticsProject)) + { + await NotificationProvider.ShowError("Current user profile does not allow loading custom diagnostics projects."); + return; + } + + if (File.Exists(package.File)) + { + try + { + LogManager.Log("Opening diagnostics project from file association..."); + await NavigationManager.NavigateTo(true, nameof(DiagnosticsView)); + using (NotificationProvider.PushTaskItem("Loading diagnostics project...")) + { + await Task.Delay(2000); + await LoadProject(package.File); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to handle the diagnostics file association."); + } + } + } + + #endregion } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Help/proc-doc.chm b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Help/proc-doc.chm index 861555098..1fb821112 100644 Binary files a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Help/proc-doc.chm and b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Help/proc-doc.chm differ diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Tango.FSE.Procedures.Documentation.shfbproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Tango.FSE.Procedures.Documentation.shfbproj index 7a0935061..abb8a83f9 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Tango.FSE.Procedures.Documentation.shfbproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures.Documentation/Tango.FSE.Procedures.Documentation.shfbproj @@ -80,6 +80,7 @@ + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Navigation/RunProcedureNavigationObject.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Navigation/RunProcedureNavigationObject.cs index b91d6ca03..c19857c21 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Navigation/RunProcedureNavigationObject.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Navigation/RunProcedureNavigationObject.cs @@ -9,5 +9,6 @@ namespace Tango.FSE.Procedures.Navigation public class RunProcedureNavigationObject { public ProcedureProject Project { get; set; } + public bool StartProcedure { get; set; } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs index 34510e54c..e9c476a20 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs @@ -21,6 +21,7 @@ using Tango.Core.Commands; using Tango.Core.ExtensionMethods; using Tango.Core.Helpers; using Tango.FSE.Common; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.Notifications; using Tango.FSE.Procedures.Contracts; @@ -454,6 +455,8 @@ namespace Tango.FSE.Procedures.ViewModels LogManager.Log(ex, "Error generating procedure designer auto creation groups."); } }); + + FileAssociationProvider.RegisterFileAssociationHandler("designer", HandlerProcedureFileAssociation); } public override void OnNavigatedTo() @@ -658,7 +661,8 @@ namespace Tango.FSE.Procedures.ViewModels { await NavigationManager.NavigateWithObject(new RunProcedureNavigationObject() { - Project = Project + Project = Project, + StartProcedure = true }); } } @@ -907,6 +911,12 @@ namespace Tango.FSE.Procedures.ViewModels private void OpenProject(String file) { + if (Project != null && Project.IsRunning) + { + NotificationProvider.ShowError("Cannot load a project while another project is running."); + return; + } + try { Project = ProcedureProject.FromJson(File.ReadAllText(file)); @@ -1517,5 +1527,32 @@ namespace Tango.FSE.Procedures.ViewModels } #endregion + + #region File Association + + private void HandlerProcedureFileAssociation(FileAssociationPackage package) + { + if (!CurrentUser.HasPermission(Permissions.FSE_RunProcedureDesigner)) + { + NotificationProvider.ShowError("Current user profile does not allow running the procedure designer."); + return; + } + + if (File.Exists(package.File)) + { + try + { + LogManager.Log("Opening procedure project from file association..."); + NavigationManager.NavigateTo(true, nameof(ProcedureDesignerView)); + OpenProject(package.File); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to handle the procedure file association."); + } + } + } + + #endregion } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureRunnerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureRunnerViewVM.cs index d69ba63f8..6ccc77669 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureRunnerViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureRunnerViewVM.cs @@ -1,19 +1,14 @@ using System; -using System.Collections; using System.Collections.Generic; -using System.ComponentModel; +using System.IO; using System.Linq; -using System.Reflection; -using System.Text; using System.Threading.Tasks; using Tango.BL.Entities; using Tango.Core; using Tango.Core.Commands; -using Tango.CSV; using Tango.FSE.Common; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Navigation; -using Tango.FSE.Procedures.CSV; -using Tango.FSE.Procedures.Dialogs; using Tango.FSE.Procedures.Messages; using Tango.FSE.Procedures.Navigation; using Tango.FSE.Procedures.Views; @@ -29,8 +24,8 @@ namespace Tango.FSE.Procedures.ViewModels } private bool _requiresReloadingOfProjects; - private bool _isFromDesigner; - private ProcedureProject _designerProject; + private bool _isFromNavigation; + private RunProcedureNavigationObject _navigationObject; private RunnerView _selectedView; public RunnerView SelectedView @@ -121,6 +116,13 @@ namespace Tango.FSE.Procedures.ViewModels RegisterForMessage((x) => _requiresReloadingOfProjects = true); } + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + + FileAssociationProvider.RegisterFileAssociationHandler("procedure", HandlerProcedureFileAssociation); + } + private async void StartProject() { try @@ -192,18 +194,22 @@ namespace Tango.FSE.Procedures.ViewModels LoadPublishedProcedureProjects(); } - if (_isFromDesigner) + if (_isFromNavigation) { if (!IsRunning) { - RunningProcedureProject = _designerProject; + RunningProcedureProject = _navigationObject.Project; RaisePropertyChanged(nameof(HasProcedureInputs)); ProjectRunner = new ProjectRunner(RunningProcedureProject); ProjectRunner.StateChanged += (x, e) => InvalidateRelayCommands(); Status = "Ready"; InvalidateRelayCommands(); SelectedView = RunnerView.ProcedureRunnerExecutionView; - StartProject(); + + if (_navigationObject.StartProcedure) + { + StartProject(); + } } else { @@ -252,16 +258,16 @@ namespace Tango.FSE.Procedures.ViewModels { SelectedView = RunnerView.ProcedureRunnerCatalogView; - if (_isFromDesigner) + if (_isFromNavigation) { - _isFromDesigner = false; + _isFromNavigation = false; return Task.FromResult(true); } return Task.FromResult(false); } - _isFromDesigner = false; + _isFromNavigation = false; return base.OnNavigateBackRequest(); } @@ -283,8 +289,28 @@ namespace Tango.FSE.Procedures.ViewModels public void OnNavigatedToWithObject(RunProcedureNavigationObject obj) { - _isFromDesigner = true; - _designerProject = obj.Project; + _isFromNavigation = true; + _navigationObject = obj; + } + + private async void HandlerProcedureFileAssociation(FileAssociationPackage package) + { + if (File.Exists(package.File)) + { + try + { + ProcedureProject project = ProcedureProject.FromJson(File.ReadAllText(package.File)); + LogManager.Log("Loading procedure from file association..."); + await NavigationManager.NavigateWithObject(new RunProcedureNavigationObject() + { + Project = project + }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to handler the procedure file association."); + } + } } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs index accc8d111..ce01b5804 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs @@ -5,10 +5,13 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL.Entities; +using Tango.BL.Enumerations; using Tango.Core.Commands; using Tango.FSE.Common; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.RemoteUpgrade; +using Tango.FSE.Upgrade.Views; using static Tango.FSE.Upgrade.ViewModels.FirmwareUpgradeGeneratedViewVM; namespace Tango.FSE.Upgrade.ViewModels @@ -102,6 +105,8 @@ namespace Tango.FSE.Upgrade.ViewModels base.OnApplicationStarted(); MachineProvider.MachineConnected += (_, __) => InvalidateCanUpgradeNow(); MachineProvider.MachineDisconnected += (_, __) => InvalidateCanUpgradeNow(); + + FileAssociationProvider.RegisterFileAssociationHandler("tfp", HandleTfpFileAssociation); } private void InvalidateCanUpgradeNow() @@ -199,7 +204,6 @@ namespace Tango.FSE.Upgrade.ViewModels IsCompleted = false; SelectedVersion = null; IsUpgradeNowSelected = true; - TfpFileLocation = null; InvalidateRelayCommands(); } @@ -235,5 +239,39 @@ namespace Tango.FSE.Upgrade.ViewModels return true; } + + private void HandleTfpFileAssociation(FileAssociationPackage package) + { + if (!IsFree) + { + NotificationProvider.ShowError("Cannot perform firmware upgrade while another upgrade is running."); + return; + } + + if (!CurrentUser.HasPermission(Permissions.FSE_RemoteUpgradeOnline)) + { + NotificationProvider.ShowError("Current user profile does not allow online remote upgrade."); + return; + } + + if (File.Exists(package.File)) + { + try + { + LogManager.Log("Performing remote firmware upgrade from file association..."); + Handler = new RemoteUpgradeHandler("Ready"); + IsCompleted = false; + TfpFileLocation = package.File; + IsUsingExistingTfp = true; + InvalidateCanUpgradeNow(); + NavigationManager.NavigateTo(true); + ModularNavigationManager.NavigateTo(Navigation.RemoteUpgradeView.FirmwareUpgradeGeneratedView); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while trying to handle the tfp file association."); + } + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml index 6aeb0fcb1..3e93300c0 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml @@ -60,7 +60,7 @@ - + I already have the .tfp file and just want to upgrade the currently connected machine. (requires an active machine connection) diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs index c3f54d0e2..5f72fbd29 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEApplication/IFSEApplicationManager.cs @@ -63,6 +63,11 @@ namespace Tango.FSE.Common.FSEApplication /// void Restart(); + /// + /// Activates the main window if it's not in focus. + /// + void ActivateMainWindow(); + /// /// Gets the application version. /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs index 352294e0a..c85a5fd35 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSESettings.cs @@ -141,6 +141,11 @@ namespace Tango.FSE.Common /// public bool TerminatedExpectedly { get; set; } + /// + /// Gets or sets the file association service port. + /// + public int FileAssociationServicePort { get; set; } + /// /// Initializes a new instance of the class. /// @@ -158,6 +163,7 @@ namespace Tango.FSE.Common AutoCheckForUpdates = true; EnableAdaptiveScaling = true; TerminatedExpectedly = true; + FileAssociationServicePort = 1800; } } } \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs index d6e3a5b52..07d2a7a5b 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs @@ -43,6 +43,7 @@ using Tango.FSE.Common.Tiles; using Tango.FSE.Common.RemoteJob; using Tango.FSE.Common.WindowsManager; using Tango.FSE.Common.DemoMode; +using Tango.FSE.Common.FileAssociation; namespace Tango.FSE.Common { @@ -228,6 +229,12 @@ namespace Tango.FSE.Common [TangoInject] public IDemoModeManager DemoModeManager { get; set; } + /// + /// Gets or sets the file association provider. + /// + [TangoInject] + public IFileAssociationProvider FileAssociationProvider { get; set; } + /// /// Gets or sets the FSE service. /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/FileAssociationPackage.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/FileAssociationPackage.cs index 106c37f16..ec072e7b1 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/FileAssociationPackage.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/FileAssociationPackage.cs @@ -8,6 +8,7 @@ namespace Tango.FSE.Common.FileAssociation { public class FileAssociationPackage { + public String TargetName { get; set; } public String File { get; set; } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/IFileAssociationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/IFileAssociationProvider.cs index 6b4440f41..2517ba82c 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/IFileAssociationProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileAssociation/IFileAssociationProvider.cs @@ -6,8 +6,9 @@ using System.Threading.Tasks; namespace Tango.FSE.Common.FileAssociation { - public interface IFileAssociationProvider + public interface IFileAssociationProvider : INotifyApplicationStarted, INotifyApplicationReady { + bool HasStartArgsPackage { get; } void RegisterFileAssociationHandler(String targetName, Action handler); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs index ddcc5dc8f..2efd3c75d 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs @@ -106,9 +106,10 @@ namespace Tango.FSE.Common.Navigation /// The type of the view. /// The type of the pass. /// The object. - /// if set to true [push to history]. + /// Push the current view to history ?. + /// Force the navigation even if we are on the same view. /// - Task NavigateWithObject(TPass obj, bool pushToHistory = true) + Task NavigateWithObject(TPass obj, bool pushToHistory = true, bool force = false) where TModule : IFSEModule; /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs index 196978f69..de0594703 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Configuration; using System.Data; @@ -14,11 +15,14 @@ using Tango.Core.DI; using Tango.Core.Helpers; using Tango.FSE.Common; using Tango.FSE.Common.BugReporting; +using Tango.FSE.Common.FileAssociation; using Tango.FSE.Common.Helpers; using Tango.FSE.Common.Notifications; +using Tango.FSE.UI.FileAssociation; using Tango.Integration.Operation; using Tango.Logging; using Tango.Settings; +using ZetaIpc.Runtime.Client; namespace Tango.FSE.UI { @@ -51,26 +55,42 @@ namespace Tango.FSE.UI protected override void OnStartup(StartupEventArgs e) { - if (e.Args != null) + try { - if (e.Args.Length == 3) + if (e.Args != null) { - if (e.Args[0] == "-file") + if (e.Args.Length == DefaultFileAssociationProvider.FILE_ASSOCIATION_ARGS_COUNT) { - if (mutex.WaitOne(TimeSpan.Zero, true)) - { - mutex.ReleaseMutex(); - MessageBox.Show($"Run Procedure {e.Args[2]} on this instance."); - } - else + if (e.Args[0] == DefaultFileAssociationProvider.FILE_ASSOCIATION_PREFIX) { - MessageBox.Show($"Run Procedure {e.Args[2]} on another instance."); - Environment.Exit(0); - return; + if (mutex.WaitOne(TimeSpan.Zero, true)) + { + //This is the first instance. Do nothing... + mutex.ReleaseMutex(); + } + else + { + //MessageBox.Show($"Run Procedure {e.Args[2]} on another instance."); + var settings = SettingsManager.Default.GetOrCreate(); + var ipcClient = new IpcClient(); + ipcClient.Initialize(settings.FileAssociationServicePort); + ipcClient.Send(JsonConvert.SerializeObject(new FileAssociationPackage() + { + TargetName = e.Args[1], + File = e.Args[2] + })); + Thread.Sleep(1000); + Environment.Exit(0); + return; + } } } } } + catch (Exception ex) + { + Debug.WriteLine(ex); + } //Set culture info. var enUSCulture = new CultureInfo("en-US"); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs index 48087bff9..aa5d4a629 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FSEApplication/DefaultFSEApplicationManager.cs @@ -457,5 +457,16 @@ namespace Tango.FSE.UI.FSEApplication return StartupArgs.Contains("-demo"); } } + + /// + /// Activates the main window if it's not in focus. + /// + public void ActivateMainWindow() + { + MainWindow.Instance.Dispatcher.BeginInvoke(new Action(() => + { + MainWindow.Instance.Activate(); + })); + } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationHandler.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationHandler.cs deleted file mode 100644 index 88f4fff05..000000000 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationHandler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.FSE.Common.FileAssociation; - -namespace Tango.FSE.UI.FileAssociation -{ - public class DefaultFileAssociationHandler : IFileAssociationProvider - { - private Dictionary> _handlers; - - public DefaultFileAssociationHandler() - { - _handlers = new Dictionary>(); - } - - public void RegisterFileAssociationHandler(string targetName, Action handler) - { - _handlers.Add(targetName.ToLower(), handler); - } - } -} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs new file mode 100644 index 000000000..9e2997e92 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileAssociation/DefaultFileAssociationProvider.cs @@ -0,0 +1,136 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.FSE.Common; +using Tango.FSE.Common.FileAssociation; +using Tango.FSE.Common.FSEApplication; +using Tango.FSE.Common.Threading; +using Tango.Logging; +using ZetaIpc.Runtime.Server; + +namespace Tango.FSE.UI.FileAssociation +{ + [TangoCreateWhenRegistered] + public class DefaultFileAssociationProvider : FSEExtendedObject, IFileAssociationProvider + { + private Dictionary> _handlers; + private IpcServer _ipcServer; + + public const string FILE_ASSOCIATION_PREFIX = "-file"; + public const int FILE_ASSOCIATION_ARGS_COUNT = 3; + + public bool HasStartArgsPackage { get; private set; } + + [TangoInject] + private IDispatcherProvider DispatcherProvider { get; set; } + + [TangoInject] + private IFSEApplicationManager ApplicationManager { get; set; } + + public DefaultFileAssociationProvider() + { + _handlers = new Dictionary>(); + _ipcServer = new IpcServer(); + } + + public void RegisterFileAssociationHandler(string targetName, Action handler) + { + _handlers.Add(targetName.ToLower(), handler); + } + + public async void OnApplicationReady(IFSEApplicationManager applicationManager) + { + try + { + LogManager.Log("Starting file association IPC service..."); + _ipcServer.Start(Settings.FileAssociationServicePort); + _ipcServer.ReceivedRequest += _ipcServer_ReceivedRequest; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error starting file association IPC service. Another instance of the application might already be running..."); + } + + var args = applicationManager.StartupArgs; + + LogManager.Log("Processing file association if any..."); + + if (args.Count == FILE_ASSOCIATION_ARGS_COUNT) + { + if (args[0] == FILE_ASSOCIATION_PREFIX) + { + + //This delay is a workaround for when the invoked handler navigates to some module. + //The navigation system does not catches the navigation request properly... :/ + await Task.Delay(500); + + LogManager.Log($"File association package found: '{String.Join(" ", args)}'. Invoking handler..."); + + try + { + String targetName = args[1].ToLower(); + + if (_handlers.ContainsKey(targetName)) + { + var package = new FileAssociationPackage() + { + TargetName = targetName, + File = args[2] + }; + + _handlers[targetName].Invoke(package); + } + else + { + LogManager.Log("File association handler not found.", LogCategory.Warning); + } + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error invoking file association handler for package '{String.Join(" ", args)}'."); + } + } + } + } + + private void _ipcServer_ReceivedRequest(object sender, ReceivedRequestEventArgs e) + { + try + { + e.Handled = true; + LogManager.Log($"File association package received through IPC server.\n{e.Request}\nInvoking handler..."); + + var package = JsonConvert.DeserializeObject(e.Request); + + if (_handlers.ContainsKey(package.TargetName.ToLower())) + { + DispatcherProvider.Invoke(() => + { + ApplicationManager.ActivateMainWindow(); + _handlers[package.TargetName.ToLower()].Invoke(package); + }); + } + else + { + LogManager.Log($"Handler not found for target '{package.TargetName}'.", LogCategory.Warning); + } + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error invoking file association handler."); + } + } + + public void OnApplicationStarted(IFSEApplicationManager applicationManager) + { + HasStartArgsPackage = + applicationManager.StartupArgs.Count == FILE_ASSOCIATION_ARGS_COUNT + && + applicationManager.StartupArgs[0] == FILE_ASSOCIATION_PREFIX; + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs index 9de496793..7a55b085a 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs @@ -44,6 +44,7 @@ namespace Tango.FSE.UI.Navigation private Object _currentVM; private String _lastFullPath; private bool _preventHistory; + private bool _force; private Stack _navigationHistory; @@ -242,7 +243,7 @@ namespace Tango.FSE.UI.Navigation { try { - if (_lastFullPath == fullPath) + if (_lastFullPath == fullPath && !_force) { return true; } @@ -450,12 +451,15 @@ namespace Tango.FSE.UI.Navigation /// The type of the view. /// The type of the pass. /// The object. - /// if set to true [push to history]. + /// Push the current view to history ?. + /// Force the navigation even if we are on the same view. /// - public Task NavigateWithObject(TPass obj, bool pushToHistory = true) where TModule : IFSEModule + public Task NavigateWithObject(TPass obj, bool pushToHistory = true, bool force = false) where TModule : IFSEModule { + _force = true; return NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (fromVM, toVM) => { + _force = false; if (toVM is INavigationObjectReceiver) { (toVM as INavigationObjectReceiver).OnNavigatedToWithObject(obj); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj index 44a163326..3d5fa6db1 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj @@ -200,6 +200,9 @@ + + ..\..\packages\ZetaIpc.1.0.0.9\lib\netstandard2.0\ZetaIpc.dll + @@ -271,7 +274,7 @@ - + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs index 13520ec7e..25d0b45c9 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs @@ -64,6 +64,8 @@ using Tango.FSE.Common.DemoMode; using Tango.FSE.UI.DemoMode; using Tango.FSE.Common.SQL; using Tango.FSE.UI.SQL; +using Tango.FSE.Common.FileAssociation; +using Tango.FSE.UI.FileAssociation; namespace Tango.FSE.UI { @@ -101,6 +103,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); @@ -138,6 +141,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs index 5c4f1b11a..9a5433f82 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/LoginViewVM.cs @@ -232,6 +232,14 @@ namespace Tango.FSE.UI.ViewModels { this.SetFocus(() => Password); } + + if (RememberMe) + { + if (FileAssociationProvider.HasStartArgsPackage) + { + Login(); + } + } } /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config b/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config index d0abb0ebf..4fda0a885 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/packages.config @@ -68,4 +68,5 @@ + \ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs index 387430f89..b9dacfcf9 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs @@ -200,7 +200,7 @@ namespace Tango.MachineService.Controllers String comments = String.Join(Environment.NewLine, versions.OrderBy(x => Version.Parse(x.Version)).Where(x => Version.Parse(x.Version) > currentVersion).Select(x => x.Comments)); - if (latestVersion != null && Version.Parse(latestVersion.Version) != currentVersion) + if (latestVersion != null && Version.Parse(latestVersion.Version) > currentVersion) { var manager = new BlobStorageManager(); var container = manager.GetContainer(MachineServiceConfig.FSE_VERSIONS_CONTAINER); diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs index a6aa93dee..704da0c08 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyVersion("3.0.2.0")] -- cgit v1.3.1