aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Synchronization/DiffAction.cs
blob: 41991eecb3b3aad96024876d9b7a5ea386e8b9be (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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tango.Synchronization
{
    /// <summary>
    /// Represents the available types of <see cref="Diff"/> actions.
    /// </summary>
    public enum DiffAction
    {
        /// <summary>
        /// Add table to slave
        /// </summary>
        AddTableToSlave,
        /// <summary>
        /// Add column to slave
        /// </summary>
        AddColumnToSlave,
        /// <summary>
        /// Add row to slave
        /// </summary>
        AddRowToSlave,
        /// <summary>
        /// Add row to master
        /// </summary>
        AddRowToMaster,
        /// <summary>
        /// Update row in slave
        /// </summary>
        UpdateRowInSlave,
        /// <summary>
        /// Update row in master
        /// </summary>
        UpdateRowInMaster,
        /// <summary>
        /// Replace table data in slave
        /// </summary>
        ReplaceTableDataInSlave,
        /// <summary>
        /// Replace table data in master
        /// </summary>
        ReplaceTableDataInMaster,
    }
}
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;

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 List<Window> _openedWindows;

        /// <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)
        {
            _moduleLoader = moduleLoader;
            _navigationManager = navigationManager;
            _openedWindows = new List<Window>();

            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;
            }

        }

        /// <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,
                                });
                            }
                        });
                    }

                    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); };
        }

        /// <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 => x.OnApplicationReady());
        }

        /// <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;
            }
        }
    }
}