using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL.Enumerations; using Tango.BL.Helpers; using Tango.Core.Commands; using Tango.Core.DI; using Tango.Core.IO; using Tango.Core.Threading; using Tango.CSV; using Tango.FSE.Common; using Tango.FSE.Common.HotFolder; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.Notifications; using Tango.FSE.Common.RemoteJobUpload; using Tango.FSE.UI.Dialogs; using Tango.FSE.UI.Panes; using Tango.FSE.UI.Views; using Tango.Integration.ExternalBridge; using Tango.PPC.Shared.Statistics; using Tango.SharedUI.Helpers; using Tango.Transport; using static Tango.BL.Helpers.SegmentsCsvHelper; namespace Tango.FSE.UI.ViewModels { /// /// Represents the application main layout view model. /// /// public class LayoutViewVM : FSEViewModel { private ActionTimer _transportOutActionTimer; private ActionTimer _transportInActionTimer; #region Properties private bool _isConnectionPaneOpened; /// /// Gets or sets a value indicating whether the machine connection pane is opened. /// public bool IsConnectionPaneOpened { get { return _isConnectionPaneOpened; } set { _isConnectionPaneOpened = value; RaisePropertyChangedAuto(); OnConnectionPaneToggleChanged(); } } private MachineConnectionPaneVM _connectionPaneVM; /// /// Gets or sets the machine connection pane view model. /// public MachineConnectionPaneVM ConnectionPaneVM { get { return _connectionPaneVM; } set { _connectionPaneVM = value; RaisePropertyChangedAuto(); } } private ConnectedMachinePaneVM _connectedMachinePaneVM; /// /// Gets or sets the connected machine pane view model. /// public ConnectedMachinePaneVM ConnectedMachinePaneVM { get { return _connectedMachinePaneVM; } set { _connectedMachinePaneVM = value; RaisePropertyChangedAuto(); } } private LogViewerPaneVM _logViewPaneVM; /// /// Gets or sets the log viewer pane view model. /// public LogViewerPaneVM LogViewerPaneVM { get { return _logViewPaneVM; } set { _logViewPaneVM = value; RaisePropertyChangedAuto(); } } private bool _isMenuOpened; /// /// Gets or sets a value indicating whether the main menu is opened. /// public bool IsMenuOpened { get { return _isMenuOpened; } set { _isMenuOpened = value; RaisePropertyChangedAuto(); } } private bool _isLogsOpened; /// /// Gets or sets a value indicating whether the log viewer is opened. /// public bool IsLogsOpened { get { return _isLogsOpened; } set { _isLogsOpened = value; RaisePropertyChangedAuto(); } } private bool _transportOut; /// /// Transport out on/off. /// public bool TransportOut { get { return _transportOut; } set { _transportOut = value; RaisePropertyChanged(nameof(TransportOut)); } } private bool _transportIn; /// /// Transport in on/off. /// public bool TransportIn { get { return _transportIn; } set { _transportIn = value; RaisePropertyChanged(nameof(TransportIn)); } } [TangoInject] public IHotFolderService HotFolderService { get; set; } [TangoInject] public IRemoteJobUploadProvider RemoteJobUploadProvider { get; set; } #endregion #region Commands /// /// Toggles the connection pane visibility. /// public RelayCommand ToggleConnectionPaneCommand { get; set; } /// /// Logs outs the current user. /// public RelayCommand LogoutCommand { get; set; } /// /// Opens the bug report dialog. /// public RelayCommand ReportIssueCommand { get; set; } /// /// Navigates to the events view. /// public RelayCommand NavigateToEventsCommand { get; set; } /// /// Navigates to the home view. /// public RelayCommand NavigateHomeCommand { get; set; } /// /// Opens the hot folder configuration dialog. /// public RelayCommand ConfigureHotFolderCommand { get; set; } /// /// Opens the job upload dialog. /// public RelayCommand UploadJobCommand { get; set; } #endregion #region Constructors /// /// Initializes a new instance of the class. /// public LayoutViewVM() { ToggleConnectionPaneCommand = new RelayCommand(() => IsConnectionPaneOpened = !IsConnectionPaneOpened); ConnectionPaneVM = new MachineConnectionPaneVM(); ConnectionPaneVM.MachineSelected += ConnectionPaneVM_MachineSelected; ConnectedMachinePaneVM = new ConnectedMachinePaneVM(); ConnectedMachinePaneVM.DisconnectedFromMachine += ConnectedMachinePaneVM_DisconnectedFromMachine; LogViewerPaneVM = new LogViewerPaneVM(); LogoutCommand = new RelayCommand(Logout); _transportOutActionTimer = new ActionTimer(TimeSpan.FromMilliseconds(50)); _transportInActionTimer = new ActionTimer(TimeSpan.FromMilliseconds(50)); ReportIssueCommand = new RelayCommand(OpenBugReportDialog); NavigateToEventsCommand = new RelayCommand(NavigateToEvents); NavigateHomeCommand = new RelayCommand(NavigateHome); ConfigureHotFolderCommand = new RelayCommand(ConfigureHotFolder); UploadJobCommand = new RelayCommand(UploadJob); } #endregion #region Machine Operator Event Handlers private void MachineProvider_MachineDisconnected(object sender, Common.Connection.MachineDisconnectedEventArgs e) { if (e.MachineOperator.Adapter != null) { e.MachineOperator.Adapter.PropertyChanged -= Adapter_PropertyChanged; } } private void MachineProvider_MachineConnected(object sender, Common.Connection.MachineConnectedEventArgs e) { e.MachineOperator.Adapter.PropertyChanged -= Adapter_PropertyChanged; e.MachineOperator.Adapter.PropertyChanged += Adapter_PropertyChanged; } private void Adapter_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == nameof(ITransportAdapter.TotalBytesSent)) { TransportOut = true; _transportOutActionTimer.ResetReplace(() => TransportOut = false); } else if (e.PropertyName == nameof(ITransportAdapter.TotalBytesReceived)) { TransportIn = true; _transportInActionTimer.ResetReplace(() => TransportIn = false); } } #endregion #region Connected Machine Pane Event Handlers private async void ConnectedMachinePaneVM_DisconnectedFromMachine(object sender, EventArgs e) { IsConnectionPaneOpened = false; try { await MachineProvider.DisconnectMachine(); } catch (Exception ex) { LogManager.Log(ex, "Error disconnecting from machine."); await NotificationProvider.ShowError("Error occurred while trying to disconnect from the machine."); } } #endregion #region Machine Connection Pane Event Handlers private async void ConnectionPaneVM_MachineSelected(object sender, IExternalBridgeClient machine) { IsConnectionPaneOpened = false; LogManager.Log($"Machine '{machine.SerialNumber}' selected for connection by user."); try { if (await MachineProvider.ConnectToMachine(machine)) { NotificationProvider.PushSnackbarItem(MessageType.Success, "Machine successfully connected", true, $"{MachineProvider.Machine.SerialNumber}, {MachineProvider.Machine.Name}", TimeSpan.FromSeconds(5)); } } catch (Exception ex) { await NotificationProvider.ShowError($"Error occurred while trying to connect to the specified machine.\n{ex.FlattenMessage()}"); LogManager.Log(ex, $"Error connecting to machine '{machine.SerialNumber}'."); } } #endregion #region Override Methods public override void OnApplicationStarted() { MachineProvider.MachineDisconnected += MachineProvider_MachineDisconnected; MachineProvider.MachineConnected += MachineProvider_MachineConnected; } public override void OnNavigatedTo() { base.OnNavigatedTo(); this.SetFocus(nameof(ToggleConnectionPaneCommand)); } public override async Task OnApplicationLogout() { if (MachineProvider.IsConnected) { if (await NotificationProvider.ShowWarningQuestion("The current machine connection will be automatically closed.\nAre you sure you want to log out?")) { await MachineProvider.DisconnectMachine(); return true; } else { return false; } } else { return true; } } #endregion #region Private Methods private void OnConnectionPaneToggleChanged() { if (!MachineProvider.IsConnected) { if (IsConnectionPaneOpened) { try { ConnectionPaneVM.Start(); } catch (Exception ex) { LogManager.Log(ex, "Error while trying to initialize machine scanning."); NotificationProvider.ShowError($"Error occurred while trying to initialize machine scanning.\n{ex.FlattenMessage()}"); _isConnectionPaneOpened = false; RaisePropertyChanged(nameof(IsConnectionPaneOpened)); } } else { try { ConnectionPaneVM.Stop(); } catch (Exception ex) { LogManager.Log(ex, "Error while stopping machine scanning."); } } } } private void Logout() { LogManager.Log("Logout command pressed by user."); AuthenticationProvider.LogOut(); } private void OpenBugReportDialog() { BugReporter.ShowBugReportDialog(); } private void NavigateToEvents() { NavigationManager.NavigateTo(nameof(EventsView)); } private void NavigateHome() { NavigationManager.NavigateTo(NavigationView.Home); } private async void ConfigureHotFolder() { await NotificationProvider.ShowDialog(); } private async void UploadJob() { RequiredFiltersData data = null; try { using (NotificationProvider.PushTaskItem("Preparing job upload requirements...")) { await Task.Delay(1500); data = await StatisticsProvider.GetRequiredFiltersData(); } } catch (Exception ex) { await NotificationProvider.ShowError($"Error preparing job upload requirements.\n{ex.FlattenMessage()}"); return; } var lastSelectedRml = data.Rmls.FirstOrDefault(x => x.Guid == Settings.LastJobUploadThreadGuid); if (lastSelectedRml == null) lastSelectedRml = data.Rmls.FirstOrDefault(); var vm = await NotificationProvider.ShowDialog(new JobUploadViewVM(MachineProvider) { Rmls = data.Rmls, SelectedRML = lastSelectedRml }); if (vm.DialogResult) { TemporaryFile tmpFile = TemporaryManager.CreateImaginaryFile(".csv"); try { Settings.LastJobUploadThreadGuid = vm.SelectedRML.Guid; Settings.Save(); CsvDynamicWriter csv = new CsvDynamicWriter(); int cIndex = 0; csv.Write(1, "Index", 0, cIndex++); csv.Write(vm.SelectedRML.Name, "ThreadName", "", cIndex++); csv.Write(vm.Length, "Length", 0, cIndex++); csv.Write(ColorSpaces.Volume, "ColorSpace", ColorSpaces.Volume, cIndex++); foreach (var liquidVolume in vm.Volumes) { if (liquidVolume.Volume > 0) { csv.Write(liquidVolume.Volume, liquidVolume.LiquidType.DisplayName, 0, cIndex); } } csv.Save(tmpFile); } catch (Exception ex) { await NotificationProvider.ShowError($"Error creating job upload file.\n{ex.FlattenMessage()}"); tmpFile.Delete(); return; } SnackbarItem progress = null; try { progress = NotificationProvider.PushProgressSnackbar("Job Upload", $"Uploading job '{vm.Name}'..."); await Task.Delay(1500); await RemoteJobUploadProvider.UploadJob(tmpFile, PPC.Shared.RemoteJobUpload.RemoteJobUploadType.CSV, vm.Name); progress.ProgressCompleted("Job uploaded successfully", TimeSpan.FromSeconds(2)); } catch (Exception ex) { progress.ProgressFailed($"Error uploading job.\n{ex.Message}"); return; } } } #endregion } }