aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules')
0 files changed, 0 insertions, 0 deletions
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using Tango.BL;
using System.Data.Entity;
using Tango.BL.Builders;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.ColorConversion;
using Tango.Core.Commands;
using Tango.Core.Components;
using Tango.Core.DI;
using Tango.Core.ExtensionMethods;
using Tango.PPC.Common;
using Tango.PPC.Common.Connection;
using Tango.PPC.Common.ExternalBridge;
using Tango.PPC.Common.Lubrication;
using Tango.PPC.Common.Messages;
using Tango.PPC.Common.OS;
using Tango.PPC.Common.UWF;
using Tango.Settings;
using Tango.SharedUI.Components;
using Tango.WiFi;
using static Tango.Core.Components.CmdCommand;

namespace Tango.PPC.MachineSettings.ViewModels
{
    /// <summary>
    /// Represents the main view VM and entry point for <see cref="Synchronization.MyModule"/>.
    /// </summary>
    /// <seealso cref="Tango.PPC.Common.PPCViewModel" />
    public class MainViewVM : PPCViewModel
    {
        private TimeZoneInfo _previousTimeZone;
        private bool _previousEnableUWF;

        #region Classes

        public class RmlLubricationLevelSettings : RmlLubricationLevel
        {
            public String Name { get; set; }

            public RmlLubricationLevelSettings()
            {

            }

            public RmlLubricationLevelSettings(RmlLubricationLevel rmlLevel, String name)
            {
                RmlGuid = rmlLevel.RmlGuid;
                LubricationLevel = rmlLevel.LubricationLevel;
                Name = name;
            }

            public RmlLubricationLevel ToRmlLubricationLevel()
            {
                return new RmlLubricationLevel()
                {
                    RmlGuid = RmlGuid,
                    LubricationLevel = LubricationLevel,
                };
            }
        }

        #endregion

        #region Properties

        [TangoInject]
        private IOperationSystemManager OperationSystemManager { get; set; }

        [TangoInject]
        private IUnifiedWriteFilterManager UnifiedWriteFilterManager { get; set; }

        private Machine _machine;
        public Machine Machine
        {
            get { return _machine; }
            set { _machine = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<JobTypes> _selectedJobTypes;
        public SelectedObjectCollection<JobTypes> SelectedJobTypes
        {
            get { return _selectedJobTypes; }
            set { _selectedJobTypes = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<ColorSpaces> _selectedColorSpaces;
        public SelectedObjectCollection<ColorSpaces> SelectedColorSpaces
        {
            get { return _selectedColorSpaces; }
            set { _selectedColorSpaces = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<ColorSpaces> _tabsColorSpaces;
        public ObservableCollection<ColorSpaces> TabsColorSpaces
        {
            get { return _tabsColorSpaces; }
            set { _tabsColorSpaces = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<Rml> _rmls;
        public ObservableCollection<Rml> Rmls
        {
            get { return _rmls; }
            set { _rmls = value; RaisePropertyChangedAuto(); }
        }

        private ObservableCollection<SpoolType> _spoolTypes;
        public ObservableCollection<SpoolType> SpoolTypes
        {
            get { return _spoolTypes; }
            set { _spoolTypes = value; RaisePropertyChangedAuto(); }
        }

        private bool _enableHotSpot;
        public bool EnableHotSpot
        {
            get { return _enableHotSpot; }
            set { _enableHotSpot = value; RaisePropertyChangedAuto(); OnEnableHotSpotChanged(); }
        }

        private String _hotSpotPassword;
        public String HotSpotPassword
        {
            get { return _hotSpotPassword; }
            set { _hotSpotPassword = value; RaisePropertyChangedAuto(); }
        }

        private bool _enableExternalBridge;
        public bool EnableExternalBridge
        {
            get { return _enableExternalBridge; }
            set { _enableExternalBridge = value; RaisePropertyChangedAuto(); OnEnableExternalBridgeChanged(); }
        }

        private String _externalBridgePassword;
        public String ExternalBridgePassword
        {
            get { return _externalBridgePassword; }
            set { _externalBridgePassword = value; RaisePropertyChangedAuto(); }
        }

        private bool _enableRemoteAssistance;
        public bool EnableRemoteAssistance
        {
            get { return _enableRemoteAssistance; }
            set { _enableRemoteAssistance = value; RaisePropertyChangedAuto(); OnEnableRemoteAssistanceChanged(); }
        }

        private bool _enableLockScreen;
        public bool EnableLockScreen
        {
            get { return _enableLockScreen; }
            set { _enableLockScreen = value; RaisePropertyChangedAuto(); }
        }

        private int _lockScreenTimeoutMinutes;
        public int LockScreenTimeoutMinutes
        {
            get { return _lockScreenTimeoutMinutes; }
            set { _lockScreenTimeoutMinutes = value; RaisePropertyChangedAuto(); }
        }

        private String _lockScreenPassword;
        public String LockScreenPassword
        {
            get { return _lockScreenPassword; }
            set { _lockScreenPassword = value; RaisePropertyChangedAuto(); }
        }

        private Rml _defaultRML;
        public Rml DefaultRML
        {
            get { return _defaultRML; }
            set { _defaultRML = value; RaisePropertyChangedAuto(); }
        }

        private SpoolType _selectedSpoolType;
        public SpoolType SelectedSpoolType
        {
            get { return _selectedSpoolType; }
            set { _selectedSpoolType = value; RaisePropertyChangedAuto(); }
        }

        private ColorSpaces _defaultTabColorSpace;
        public ColorSpaces DefaultTabColorSpace
        {
            get { return _defaultTabColorSpace; }
            set { _defaultTabColorSpace = value; RaisePropertyChangedAuto(); }
        }

        private bool _synchronizeJobs;
        public bool SynchronizeJobs
        {
            get { return _synchronizeJobs; }
            set { _synchronizeJobs = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
        }

        private bool _synchronizeDiagnostics;
        public bool SynchronizeDiagnostics
        {
            get { return _synchronizeDiagnostics; }
            set { _synchronizeDiagnostics = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
        }

        private bool _autoCheckForUpdates;
        public bool AutoCheckForUpdates
        {
            get { return _autoCheckForUpdates; }
            set { _autoCheckForUpdates = value; RaisePropertyChangedAuto(); }
        }

        private List<TimeZoneInfo> _timeZones;
        /// <summary>
        /// Gets or sets the available time zones.
        /// </summary>
        public List<TimeZoneInfo> TimeZones
        {
            get { return _timeZones; }
            set { _timeZones = value; RaisePropertyChangedAuto(); }
        }

        private TimeZoneInfo _selectedTimeZone;
        /// <summary>
        /// Gets or sets the selected time zone.
        /// </summary>
        public TimeZoneInfo SelectedTimeZone
        {
            get { return _selectedTimeZone; }
            set { _selectedTimeZone = value; RaisePropertyChangedAuto(); }
        }

        private bool _enableUWF;
        public bool EnableUWF
        {
            get { return _enableUWF; }
            set { _enableUWF = value; RaisePropertyChangedAuto(); }
        }

        private List<RmlLubricationLevelSettings> _lubricationLevels;
        public List<RmlLubricationLevelSettings> LubricationLevels
        {
            get { return _lubricationLevels; }
            set { _lubricationLevels = value; RaisePropertyChangedAuto(); }
        }

        private RmlLubricationLevelSettings _selectedLubricationLevel;
        public RmlLubricationLevelSettings SelectedLubricationLevel
        {
            get { return _selectedLubricationLevel; }
            set { _selectedLubricationLevel = value; RaisePropertyChangedAuto(); }
        }

        private bool _useLightInks;
        public bool UseLightInks
        {
            get { return _useLightInks; }
            set { _useLightInks = value; RaisePropertyChangedAuto(); }
        }

        private bool _enableProxy;
        public bool EnableProxy
        {
            get { return _enableProxy; }
            set { _enableProxy = value; RaisePropertyChangedAuto(); }
        }

        private int _manualFineTuningLength;
        public int FineTuningLength
        {
            get { return _manualFineTuningLength; }
            set { _manualFineTuningLength = value; RaisePropertyChangedAuto(); }
        }


        #endregion

        #region Commands

        /// <summary>
        /// Gets or sets the save command.
        /// </summary>
        public RelayCommand SaveCommand { get; set; }

        /// <summary>
        /// Gets or sets the discard command.
        /// </summary>
        public RelayCommand DiscardCommand { get; set; }

        /// <summary>
        /// Gets or sets the synchronize command.
        /// </summary>
        public RelayCommand SynchronizeCommand { get; set; }

        #endregion

        public MainViewVM()
        {
            LubricationLevels = new List<RmlLubricationLevelSettings>();
            SaveCommand = new RelayCommand(Save);
            DiscardCommand = new RelayCommand(Discard);
            SynchronizeCommand = new RelayCommand(Synchronize, () => !MachineDataSynchronizer.IsSynchronizing && IsFree);
        }

        private void Discard()
        {
            NavigationManager.NavigateBack();
        }

        private async void Save()
        {
            if (Validate())
            {
                Settings.SupportedJobTypes = SelectedJobTypes.SynchedSource.ToList();
                Settings.SupportedColorSpaces = SelectedColorSpaces.SynchedSource.ToList();

                Machine.MapPropertiesTo(MachineProvider.Machine, MappingFlags.NoReferenceTypes);

                Settings.EnableHotSpot = EnableHotSpot;
                Settings.HotSpotPassword = HotSpotPassword;
                Settings.EnableExternalBridge = EnableExternalBridge;
                Settings.ExternalBridgePassword = ExternalBridgePassword;
                Settings.EnableLockScreen = EnableLockScreen;
                Settings.LockScreenTimeout = TimeSpan.FromMinutes(LockScreenTimeoutMinutes);
                Settings.LockScreenPassword = LockScreenPassword;
                Settings.DefaultRmlGuid = DefaultRML?.Guid;
                String previousSpoolType = Settings.SpoolTypeGuid;
                Settings.SpoolTypeGuid = SelectedSpoolType?.Guid;
                Settings.SynchronizeJobs = SynchronizeJobs;
                Settings.SynchronizeDiagnostics = SynchronizeDiagnostics;
                Settings.AutoCheckForUpdates = AutoCheckForUpdates;
                Settings.LubricationLevels = LubricationLevels.Where(x => x.LubricationLevel != LubricationLevel.Standard).Select(x => x.ToRmlLubricationLevel()).ToList();
                Settings.DefaultTabColorSpace = DefaultTabColorSpace;
                Settings.FineTuningTrialLengthMeters = FineTuningLength;

                MachineDataSynchronizer.IsEnabled = SynchronizeJobs || SynchronizeDiagnostics;

                var colorConversionSettings = SettingsManager.Default.GetOrCreate<ColorConversionSettings>();
                colorConversionSettings.UseLightInks = UseLightInks;

                Settings.Save();

                await MachineProvider.SaveMachine();

                bool isRestarting = false;

                if (SelectedSpoolType != null && previousSpoolType != Settings.SpoolTypeGuid)
                {
                    await MachineProvider.MachineOperator.SetSpoolType((PMR.Printing.JobSpoolType)SelectedSpoolType.Code);
                }

                if (_previousTimeZone.ToStringSafe() != SelectedTimeZone.ToStringSafe())
                {
                    if (await NotificationProvider.ShowQuestion("Changing the time zone requires the application to restart. Do you wish to restart the application?"))
                    {
                        try
                        {
                            LogManager.Log($"Setting new time zone to '{SelectedTimeZone.ToString()}'.");
                            NotificationProvider.SetGlobalBusyMessage("Setting new time zone...");
                            await OperationSystemManager.ChangeTimeZone(SelectedTimeZone);
                            NotificationProvider.ReleaseGlobalBusyMessage();
                            isRestarting = true;
                            ApplicationManager.Restart();
                        }
                        catch (Exception ex)
                        {
                            LogManager.Log(ex, "Error changing the time zone.");
                            NotificationProvider.ReleaseGlobalBusyMessage();
                            await NotificationProvider.ShowError($"Error setting timezone.\n{ex.FlattenMessage()}");
                        }
                    }
                }

                if (!BuildProvider.IsEureka)
                {
                    if (EnableProxy != Settings.EnableProxifier)
                    {
                        CmdCommand cmd = null;
                        CmdCommandResult result = null;

                        if (!EnableProxy)
                        {
                            try
                            {
                                cmd = new CmdCommand("taskkill", "/F /IM proxifier.exe");
                                result = await cmd.Run();
                                Settings.EnableProxifier = false;
                                Settings.Save();
                            }
                            catch (Exception ex)
                            {
                                LogManager.Log(ex, $"Unable to disable the proxy.\n{ex.Message}");
                                await NotificationProvider.ShowError($"Unable to disable the proxy.\n{ex.Message}");
                            }
                        }
                        else
                        {
                            try
                            {
                                Process.Start(@"C:\Program Files (x86)\Proxifier\Proxifier.exe");
                                Settings.EnableProxifier = true;
                                Settings.Save();
                            }
                            catch (Exception ex)
                            {
                                LogManager.Log(ex, $"Unable to start the proxy service.\n{ex.Message}");
                                await NotificationProvider.ShowError($"Unable to start the proxy service.\n{ex.Message}");
                            }
                        }
                    }

                    if (_previousEnableUWF != EnableUWF)
                    {
                        await NotificationProvider.ShowWarning("Changes to disk protection (UWF) will take effect only after a full system restart.");

                        try
                        {
                            LogManager.Log($"Changing UWF mode to '{EnableUWF}'.");
                            if (EnableUWF)
                            {
                                NotificationProvider.SetGlobalBusyMessage("Enabling disk protection (UWF)...");
                                await UnifiedWriteFilterManager.Enable();
                            }
                            else
                            {
                                NotificationProvider.SetGlobalBusyMessage("Disabling disk protection (UWF)...");
                                await UnifiedWriteFilterManager.Disable();
                            }
                            NotificationProvider.ReleaseGlobalBusyMessage();
                        }
                        catch (Exception ex)
                        {
                            NotificationProvider.ReleaseGlobalBusyMessage();
                            LogManager.Log(ex, "Error setting UWF mode.");
                            await NotificationProvider.ShowError($"Could not change the disk protection mode\n{ex.FlattenMessage()}");
                        }
                    }

                    if (!isRestarting)
                    {
                        await NavigationManager.NavigateBack();
                    }
                }
            }
        }

        protected override void OnValidating()
        {
            base.OnValidating();
        }

        /// <summary>
        /// Called when the application has been started
        /// </summary>
        public override void OnApplicationStarted()
        {
            try
            {
                TimeZones = OperationSystemManager.GetAvailableTimeZones().ToList();
            }
            catch (Exception ex)
            {
                LogManager.Log(ex, "Error retrieving available time zones.");
            }
        }

        public async override void OnApplicationReady()
        {
            base.OnApplicationReady();
            MachineDataSynchronizer.SynchronizationStarted += (_, __) => InvalidateRelayCommands();
            MachineDataSynchronizer.SynchronizationEnded += (_, __) => InvalidateRelayCommands();

            if (!BuildProvider.IsEureka)
            {
                if (!Settings.EnableProxifier)
                {
                    CmdCommand cmd = null;
                    CmdCommandResult result = null;

                    try
                    {
                        cmd = new CmdCommand("taskkill", "/F /IM proxifier.exe");
                        result = await cmd.Run();
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, $"Unable to disable the proxy.\n{ex.Message}");
                    }
                }
            }

            using (ObservablesContext db = ObservablesContext.CreateDefault())
            {
                Rmls = (await new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).BuildAsync()).OrderBy(x => x.FinalName).ToObservableCollection();
                SpoolTypes = await MachineProvider.Machine.GetSiteSpoolTypes(db);
            }
        }

        public async override void OnNavigatedTo()
        {
            base.OnNavigatedTo();

            Machine = MachineProvider.Machine.ShallowClone();

            RaisePropertyChanged(nameof(Machine));

            _enableHotSpot = HotSpotProvider.IsEnabled;
            RaisePropertyChanged(nameof(EnableHotSpot));

            HotSpotPassword = Settings.HotSpotPassword;

            _enableExternalBridge = ExternalBridgeService.Enabled;
            RaisePropertyChanged(nameof(EnableExternalBridge));

            ExternalBridgePassword = Settings.ExternalBridgePassword;

            _enableRemoteAssistance = RemoteAssistanceProvider.IsEnabled;
            RaisePropertyChanged(nameof(EnableRemoteAssistance));

            EnableLockScreen = Settings.EnableLockScreen;
            LockScreenTimeoutMinutes = (int)Settings.LockScreenTimeout.TotalMinutes;
            LockScreenPassword = Settings.LockScreenPassword;

            FineTuningLength = Settings.FineTuningTrialLengthMeters;

            SelectedJobTypes = new SelectedObjectCollection<JobTypes>(Enum.GetValues(typeof(JobTypes)).Cast<JobTypes>().ToObservableCollection(), Settings.SupportedJobTypes.ToObservableCollection());
            SelectedColorSpaces = new SelectedObjectCollection<ColorSpaces>(Enum.GetValues(typeof(ColorSpaces)).Cast<ColorSpaces>().Where(x => x.IsUserSpace()).ToObservableCollection(), Settings.SupportedColorSpaces.ToObservableCollection());

            TabsColorSpaces = new ObservableCollection<ColorSpaces>(Enum.GetValues(typeof(ColorSpaces)).Cast<ColorSpaces>().Where(x => x != ColorSpaces.Volume /*&& x!= ColorSpaces.HSB*/).ToObservableCollection());
            DefaultTabColorSpace = Settings.DefaultTabColorSpace == null ? ColorSpaces.CMYK : TabsColorSpaces.SingleOrDefault(x => x == Settings.DefaultTabColorSpace);

            DefaultRML = Rmls.SingleOrDefault(x => x.Guid == Settings.DefaultRmlGuid);
            SelectedSpoolType = SpoolTypes.SingleOrDefault(x => x.Guid == Settings.SpoolTypeGuid);

            if (SelectedSpoolType == null)
            {
                SelectedSpoolType = SpoolTypes.FirstOrDefault(x => x.Code == (int)BL.Enumerations.SpoolTypes.StandardSpool);
            }

            SynchronizeJobs = Settings.SynchronizeJobs;
            SynchronizeDiagnostics = Settings.SynchronizeDiagnostics;

            AutoCheckForUpdates = Settings.AutoCheckForUpdates;

            var colorConversionSettings = SettingsManager.Default.GetOrCreate<ColorConversionSettings>();
            UseLightInks = colorConversionSettings.UseLightInks;

            SelectedTimeZone = TimeZones.SingleOrDefault(x => x.StandardName == TimeZone.CurrentTimeZone.StandardName);
            _previousTimeZone = SelectedTimeZone;

            if (!BuildProvider.IsEureka)
            {
                try
                {
                    EnableUWF = await UnifiedWriteFilterManager.IsEnabled();
                    _previousEnableUWF = EnableUWF;
                }
                catch (Exception ex)
                {
                    LogManager.Log(ex, "Error getting UWF status.");
                }
            }

            try
            {
                List<RmlLubricationLevelSettings> levels = new List<RmlLubricationLevelSettings>();

                foreach (var rml in Rmls)
                {
                    RmlLubricationLevel userLevel = Settings.LubricationLevels.FirstOrDefault(x => x.RmlGuid == rml.Guid);

                    RmlLubricationLevelSettings rmlLevel = new RmlLubricationLevelSettings();
                    rmlLevel.RmlGuid = rml.Guid;
                    rmlLevel.Name = rml.Name;
                    rmlLevel.LubricationLevel = userLevel != null ? userLevel.LubricationLevel : LubricationLevel.Standard;

                    levels.Add(rmlLevel);
                }

                LubricationLevels = levels;

                if (SelectedLubricationLevel != null)
                {
                    SelectedLubricationLevel = LubricationLevels.FirstOrDefault(x => x.RmlGuid == SelectedLubricationLevel.RmlGuid);
                }
                else
                {
                    SelectedLubricationLevel = LubricationLevels.FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                LogManager.Log(ex, "Error loading lubrication levels.");
            }

            if (!BuildProvider.IsEureka)
            {
                EnableProxy = Settings.EnableProxifier;
            }
        }

        private async void OnEnableRemoteAssistanceChanged()
        {
            if (EnableRemoteAssistance)
            {
                try
                {
                    await RemoteAssistanceProvider.EnableRemoteAssistance();
                }
                catch
                {
                    await NotificationProvider.ShowError("An error occurred while trying to activate the remote assistance service. Please check your device settings and try again.");
                    _enableRemoteAssistance = false;
                }
            }
            else
            {
                try
                {
                    await RemoteAssistanceProvider.DisableRemoteAssistance();
                }
                catch
                {
                    await NotificationProvider.ShowError("An error occurred while trying to deactivate the remote assistance service. Please check your device settings and try again.");
                    _enableRemoteAssistance = true;
                }
            }

            RaisePropertyChanged(nameof(EnableRemoteAssistance));
        }

        private async void OnEnableHotSpotChanged()
        {
            if (EnableHotSpot)
            {
                if (HotSpotPassword == null || HotSpotPassword.Length < 8 || HotSpotPassword.Length > 16)
                {
                    await NotificationProvider.ShowError("Hot spot requires a password of 8 to 16 characters.");
                    _enableHotSpot = false;
                    RaisePropertyChanged(nameof(EnableHotSpot));
                    return;
                }

                try
                {
                    await HotSpotProvider.EnableHotSpot(HotSpotPassword);
                }
                catch
                {
                    await NotificationProvider.ShowError("An error occurred while trying to activate the hot spot network. Please check your device settings and try again.");
                    _enableHotSpot = false;
                }
            }
            else
            {
                try
                {
                    await HotSpotProvider.DisableHotSpot();
                }
                catch
                {
                    await NotificationProvider.ShowError("An error occurred while trying to deactivate the hot spot network.");
                    _enableHotSpot = true;
                }
            }

            RaisePropertyChanged(nameof(EnableHotSpot));
        }

        private void OnEnableExternalBridgeChanged()
        {
            ExternalBridgeService.Enabled = EnableExternalBridge;
        }

        private async void Synchronize()
        {
            try
            {
                IsFree = false;
                NotificationProvider.SetGlobalBusyMessage("Synchronizing...");

                await MachineDataSynchronizer.Synchronize();

                NotificationProvider.ReleaseGlobalBusyMessage();
                await NotificationProvider.ShowSuccess("Synchronization completed successfully.");
            }
            catch (Exception ex)
            {
                NotificationProvider.ReleaseGlobalBusyMessage();
                await NotificationProvider.ShowError($"Error occurred while trying to synchronize.\n{ex.FlattenMessage()}");
            }
            finally
            {
                NotificationProvider.ReleaseGlobalBusyMessage();
                IsFree = true;
            }
        }
    }
}