aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Synchronization/ViewModelLocator.cs
blob: 861bf56bf4d77407a4274398fe51e0c4bc9e4021 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using Tango.Core.DI;
using Tango.MachineStudio.Synchronization.Navigation;
using Tango.MachineStudio.Synchronization.ViewModels;

namespace Tango.MachineStudio.Synchronization
{
    /// <summary>
    /// This class contains static references to all the view models in the
    /// application and provides an entry point for the bindings.
    /// </summary>
    public static class ViewModelLocator
    {
        /// <summary>
        /// Initializes a new instance of the ViewModelLocator class.
        /// </summary>
        static ViewModelLocator()
        {
            TangoIOC.Default.Register<MainViewVM>();
            TangoIOC.Default.Register<MenuViewVM>();
            TangoIOC.Default.Register<LocalSynchronizationViewVM>();
            TangoIOC.Default.Register<RemoteSynchronizationViewVM>();
            TangoIOC.Default.Register<DirectSynchronizationViewVM>();

            TangoIOC.Default.Unregister<SyncNavigationManager>();

            TangoIOC.Default.Register<SyncNavigationManager, SyncNavigationManager>();
        }

        public static MainViewVM MainViewVM
        {
            get
            {
                return TangoIOC.Default.GetInstance<MainViewVM>();
            }
        }

        public static MenuViewVM MenuViewVM
        {
            get
            {
                return TangoIOC.Default.GetInstance<MenuViewVM>();
            }
        }

        public static LocalSynchronizationViewVM LocalSynchronizationViewVM
        {
            get
            {
                return TangoIOC.Default.GetInstance<LocalSynchronizationViewVM>();
            }
        }

        public static RemoteSynchronizationViewVM RemoteSynchronizationViewVM
        {
            get
            {
                return TangoIOC.Default.GetInstance<RemoteSynchronizationViewVM>();
            }
        }

        public static DirectSynchronizationViewVM DirectSynchronizationViewVM
        {
            get
            {
                return TangoIOC.Default.GetInstance<DirectSynchronizationViewVM>();
            }
        }
    }
}
2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tango.Core.Helpers;
using Tango.MachineStudio.Common.StudioApplication;
using Tango.MachineStudio.Common.Navigation;
using System.Reflection;
using System.Collections;
using Tango.Core;
using Tango.Logging;
using Tango.MachineStudio.Common.Modules;
using Tango.MachineStudio.Common;
using Tango.Settings;
using System.Windows;
using Tango.Integration.ExternalBridge;
using Tango.MachineStudio.Common.EventLogging;
using Tango.BL.Enumerations;
using Tango.Core.DI;
using Tango.BL.Entities;
using Tango.BL;
using Tango.MachineStudio.UI.ViewModels;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.UI.Views;
using Tango.Integration.Operation;
using Tango.MachineStudio.UI.Windows;

namespace Tango.MachineStudio.UI.StudioApplication
{
    /// <summary>
    /// Represents the default Machine Studio <see cref="IStudioApplicationManager">Application Manager</see>.
    /// </summary>
    /// <seealso cref="Tango.Core.ExtendedObject" />
    /// <seealso cref="Tango.MachineStudio.Common.StudioApplication.IStudioApplicationManager" />
    public class DefaultStudioApplicationManager : ExtendedObject, IStudioApplicationManager
    {
        private INavigationManager _navigationManager;
        private IStudioModuleLoader _moduleLoader;
        private INotificationProvider _notification;
        private List<Window> _openedWindows;
        private List<IStudioViewModel> _notified_view_models;

        /// <summary>
        /// Initializes a new instance of the <see cref="DefaultStudioApplicationManager" /> class.
        /// </summary>
        /// <param name="navigationManager">The navigation manager.</param>
        public DefaultStudioApplicationManager(INavigationManager navigationManager, IStudioModuleLoader moduleLoader, INotificationProvider notification)
        {
            _moduleLoader = moduleLoader;
            _navigationManager = navigationManager;
            _notification = notification;
            _openedWindows = new List<Window>();
            _notified_view_models = new List<IStudioViewModel>();

            Application.Current.MainWindow.ContentRendered += (_, __) =>
            {
                TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>().ToList().ForEach(x => x.OnApplicationStarted());
            };
        }

        /// <summary>
        /// Gets a value indicating whether Machine Studio is shutting down.
        /// </summary>
        public bool IsShuttingDown { get; private set; }

        /// <summary>
        /// Occurs when the connected machine property has changed.
        /// </summary>
        public event EventHandler<IExternalBridgeClient> ConnectedMachineChanged;

        /// <summary>
        /// Gets or sets the machine.
        /// </summary>
        public Machine Machine { get; private set; }

        private IExternalBridgeClient _connectedMachine;
        /// <summary>
        /// Gets or sets the currently connected machine if any.
        /// </summary>
        public IExternalBridgeClient ConnectedMachine
        {
            get { return _connectedMachine; }
            private set
            {
                _connectedMachine = value;
                RaisePropertyChangedAuto();
                RaisePropertyChanged(nameof(IsMachineConnected));
                RaisePropertyChanged(nameof(IsMachineConnectedViaTCP));

                if (_connectedMachine != null)
                {
                    _connectedMachine.StateChanged -= ConnectedMachine_StateChanged;
                    _connectedMachine.StateChanged += ConnectedMachine_StateChanged;
                }

                ConnectedMachineChanged?.Invoke(this, _connectedMachine);
            }
        }

        /// <summary>
        /// Gets a value indicating whether the <see cref="P:Tango.MachineStudio.Common.StudioApplication.IStudioApplicationManager.ConnectedMachine" /> is valid and connected through TCP/IP.
        /// </summary>
        public bool IsMachineConnectedViaTCP
        {
            get { return IsMachineConnected && ConnectedMachine is ExternalBridgeTcpClient; }
        }

        /// <summary>
        /// Handles the <see cref="ConnectedMachine"/> state changed event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The e.</param>
        private void ConnectedMachine_StateChanged(object sender, Transport.TransportComponentState e)
        {
            if (e == Transport.TransportComponentState.Disconnected || e == Transport.TransportComponentState.Failed)
            {
                ConnectedMachine = null;

                if (e == Transport.TransportComponentState.Failed)
                {
                    String failed_reason = (sender as IMachineOperator).FailedStateException.Message;

                    ConnectionLostViewVM vm = new ConnectionLostViewVM()
                    {
                        Exception = failed_reason
                    };

                    InvokeUI(() =>
                    {
                        _notification.ShowModalDialog<ConnectionLostViewVM, ConnectionLostView>(vm, (x) => { }, () => { });
                    });
                }
            }
        }

        /// <summary>
        /// Gets a value indicating whether the <see cref="P:Tango.MachineStudio.Common.StudioApplication.IStudioApplicationManager.ConnectedMachine" /> is valid.
        /// </summary>
        public bool IsMachineConnected
        {
            get { return ConnectedMachine != null; }
        }

        /// <summary>
        /// Gets the machine studio application version.
        /// </summary>
        public Version Version
        {
            get
            {
                return AssemblyHelper.GetCurrentAssemblyVersion();
            }
        }

        /// <summary>
        /// Shutdown the application.
        /// </summary>
        public async void ShutDown()
        {
            if (IsShuttingDown) return;

            IsShuttingDown = true;

            try
            {
                Rect r = new Rect(
                        MainWindow.Instance.Left,
                        MainWindow.Instance.Top,
                        MainWindow.Instance.Width,
                        MainWindow.Instance.Height);

                await Task.Factory.StartNew(async () =>
                {
                    //Do Shutdown Procedures...
                    foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>())
                    {
                        try
                        {
                            var result = await vm.OnShutdownRequest();
                            if (!result)
                            {
                                IsShuttingDown = false;
                                return;
                            }
                        }
                        catch (Exception ex)
                        {
                            LogManager.Log(ex, "Error on shutdown request with " + vm.GetType().Name);
                        }
                    }

                    foreach (var vm in TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>())
                    {
                        vm.OnShuttingDown();
                    }


                    var settings = SettingsManager.Default.GetOrCreate<MachineStudioSettings>();
                    settings.LastBounds = r;
                    settings.StudioModulesBounds.Clear();


                    foreach (var window in _openedWindows.OfType<Windows.ModuleWindow>())
                    {
                        window.Invoke(() =>
                        {
                            var context = window.ModuleContext;

                            if (context != null)
                            {
                                settings.StudioModulesBounds.Add(new MachineStudioSettings.StudioModuleBounds()
                                {
                                    Bounds = window.RestoreBounds,
                                    State = window.WindowState,
                                    Name = context.Module.Name,
                                });
                            }
                        });
                    }

                    var mainViewVM = TangoIOC.Default.GetInstance<MainViewVM>();

                    settings.LastMainModuleName = mainViewVM.CurrentModule != null ? mainViewVM.CurrentModule.Name : null;

                    try
                    {
                        SettingsManager.Default.Save();
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, "Error saving settings.");
                    }

                    await _navigationManager.NavigateTo(NavigationView.ShutdownView);

                    Thread.Sleep(1500);

                    foreach (var window in _openedWindows)
                    {
                        ThreadsHelper.InvokeUI(() =>
                        {
                            window.Close();
                        });
                    }

                    try
                    {
                        if (ConnectedMachine != null)
                        {
                            ConnectedMachine.Disconnect().Wait();
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Log(ex, "Error disconnecting from machine.");
                    }

                    var eventLogger = TangoIOC.Default.GetInstance<IEventLogger>();
                    if (eventLogger != null)
                    {
                        eventLogger.Log(EventTypes.ApplicationTerminated, "Application Terminated!");
                        eventLogger.FlushAll();
                    }

                    Thread.Sleep(1500);

                    Environment.Exit(0);

                });
            }
            catch (Exception ex)
            {
                IsShuttingDown = false;
                LogManager.Log(ex, "An error occurred while shutting down machine studio.");
            }
        }

        /// <summary>
        /// Notify the application manager about an external opened window.
        /// When application exists. All registered windows will be closed.
        /// </summary>
        /// <param name="window">The window.</param>
        public void RegisterOpenedWindow(Window window)
        {
            _openedWindows.Add(window);

            window.Closed += (x, y) => { _openedWindows.Remove(window); };
        }

        public bool IsModuleInNewWindow(IStudioModule module)
        {
            return _openedWindows.Exists(x => (x as ModuleWindow).ModuleContext.Module == module);
        }

        /// <summary>
        /// Gets the core libraries version.
        /// </summary>
        public Version CoreVersion
        {
            get
            {
                return typeof(ExtendedObject).Assembly.GetName().Version;
            }
        }

        /// <summary>
        /// Gets the build date.
        /// </summary>
        public string BuildDate
        {
            get
            {
                return AssemblyHelper.GetCurrentAssemblyBuildDate().ToShortDateString();
            }
        }

        /// <summary>
        /// Gets the change log.
        /// </summary>
        public string ChangeLog
        {
            get
            {
                return EmbeddedResourceHelper.GetEmbeddedResourceText("Tango.MachineStudio.UI.ChangeLog.txt");
            }
        }

        /// <summary>
        /// Raises the application ready event.
        /// </summary>
        public void NotifyApplicationReady()
        {
            TangoIOC.Default.GetAllInstancesByBase<IStudioViewModel>().ToList().ForEach(x => 
            {
                if (!_notified_view_models.Contains(x))
                {
                    x.OnApplicationReady();
                    _notified_view_models.Add(x);
                }
            });
        }

        /// <summary>
        /// Sets the connected machine.
        /// </summary>
        /// <param name="connectedMachine">The connected machine.</param>
        public void SetConnectedMachine(IExternalBridgeClient connectedMachine)
        {
            if (connectedMachine != null)
            {
                Machine = ObservablesStaticCollections.Instance.Machines.SingleOrDefault(x => x.SerialNumber == connectedMachine.SerialNumber);
                ConnectedMachine = connectedMachine;
                ConnectedMachine.SetMachine(Machine);
            }
            else
            {
                Machine = null;
                ConnectedMachine = null;
            }
        }
    }
}