From 1061758f95b7ba633e6bcc2c3556b42f033b1a79 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Mon, 26 Mar 2018 14:21:53 +0300 Subject: Working on logging module ! Modified PID Control Table. --- .../Tango.MachineStudio.Logging.csproj | 4 + .../ViewModels/MainViewVM.cs | 39 +++++++-- .../Views/MainView.xaml | 15 +++- .../EventLogging/DefaultEventLogger.cs | 92 +++++++++++++++------- .../EventLogging/IEventLogger.cs | 11 +++ .../Messages/MachineConnectionChangedMessage.cs | 14 ++++ .../Tango.MachineStudio.Common.csproj | 1 + .../Tango.MachineStudio.UI/App.xaml.cs | 9 ++- .../DefaultStudioApplicationManager.cs | 9 +++ .../ViewModels/LoadingViewVM.cs | 1 - .../ViewModels/MainViewVM.cs | 34 ++++++-- 11 files changed, 187 insertions(+), 42 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Messages/MachineConnectionChangedMessage.cs (limited to 'Software/Visual_Studio/MachineStudio') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj index d62246cf2..be3e1ef93 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj @@ -150,6 +150,10 @@ {8491d07b-c1f6-4b62-a412-41b9fd2d6538} Tango.SharedUI + + {74e700b0-1156-4126-be40-ee450d3c3026} + Tango.Transport + {cb0b0aa2-bb24-4bca-a720-45e397684e12} Tango.MachineStudio.Common diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs index 94765ccdb..2b773c1c2 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs @@ -1,12 +1,16 @@ -using System; +using GalaSoft.MvvmLight.Messaging; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL; using Tango.BL.Entities; using Tango.MachineStudio.Common.EventLogging; +using Tango.MachineStudio.Common.Messages; using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Common.StudioApplication; using Tango.SharedUI; namespace Tango.MachineStudio.Logging.ViewModels @@ -14,9 +18,11 @@ namespace Tango.MachineStudio.Logging.ViewModels public class MainViewVM : ViewModel { private INotificationProvider _notification; + private IStudioApplicationManager _application; private IEventLogger _eventLogger; private DateVM _realTimeDate; private ObservableCollection _realTimeEvents; + private Machine _connectedMachine; private Machine _selectedMachine; public Machine SelectedMachine @@ -53,18 +59,37 @@ namespace Tango.MachineStudio.Logging.ViewModels set { _selectedDate = value; RaisePropertyChangedAuto(); OnSelectedDateChanged(); } } - public MainViewVM(INotificationProvider notification, IEventLogger eventLogger) + public MainViewVM(INotificationProvider notification, IEventLogger eventLogger, IStudioApplicationManager application) { + _application = application; _notification = notification; _eventLogger = eventLogger; _realTimeDate = new DateVM(DateTime.Now) { Description = "Real Time" }; _realTimeEvents = new ObservableCollection(); _eventLogger.NewLog += _eventLogger_NewLog; + + RegisterMessage(OnMachineConnectionChanged); + } + + private void OnMachineConnectionChanged(MachineConnectionChangedMessage msg) + { + if (msg.Machine != null) + { + _connectedMachine = ObservablesEntitiesAdapter.Instance.Machines.SingleOrDefault(x => x.SerialNumber == msg.Machine.SerialNumber); + SelectedMachine = _connectedMachine; + } + else + { + _connectedMachine = null; + } } private void _eventLogger_NewLog(object sender, MachinesEvent machineEvent) { - _realTimeEvents.Add(machineEvent); + InvokeUI(() => + { + _realTimeEvents.Add(machineEvent); + }); } private void OnSelectedMachineChanged() @@ -72,14 +97,18 @@ namespace Tango.MachineStudio.Logging.ViewModels if (SelectedMachine != null) { Dates = new ObservableCollection(); - Dates.Add(_realTimeDate); + + if (SelectedMachine == _connectedMachine) + { + Dates.Add(_realTimeDate); + } foreach (var day in SelectedMachine.MachinesEvents.GroupBy(x => x.DateTime.DayOfYear).Select(x => x.First().DateTime).OrderByDescending(x => x)) { Dates.Add(new DateVM(day)); } - SelectedDate = Dates.First(); + SelectedDate = Dates.FirstOrDefault(); } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml index d4567d90f..3d59ee88e 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml @@ -74,7 +74,7 @@ - + @@ -118,6 +125,10 @@ + + + + @@ -127,7 +138,7 @@ - + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs index 0f19d3b6d..d3fb0897f 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/DefaultEventLogger.cs @@ -34,13 +34,14 @@ namespace Tango.MachineStudio.Common.EventLogging private Dictionary _eventTypesGuids; private String _hostName; private bool _isInitialized; + private List _pendingEvents; #region Events /// /// Occurs when a new machine event has been logged. /// - public event EventHandler NewLog; + public event EventHandler NewLog; #endregion @@ -56,6 +57,7 @@ namespace Tango.MachineStudio.Common.EventLogging _hostName = Environment.MachineName; _events = new ConcurrentQueue(); + _pendingEvents = new List(); _eventTypesGuids = new Dictionary(); @@ -90,7 +92,7 @@ namespace Tango.MachineStudio.Common.EventLogging _eventTypesGuids.Add((EventTypes)type.Code, type); } - _isInitialized = true; + _isInitialized = true; } } @@ -176,15 +178,33 @@ namespace Tango.MachineStudio.Common.EventLogging /// The machine event. public void Log(MachinesEvent machineEvent) { - machineEvent.MachineGuid = _application.ConnectedMachine != null ? _application.ConnectedMachine.Guid : null; - machineEvent.UserGuid = _authentication.CurrentUser != null ? _authentication.CurrentUser.Guid : null; machineEvent.HostName = _hostName; machineEvent.EventType = _eventTypesGuids[machineEvent.Type]; - LogManager.Log("Logging event " + machineEvent.EventType.Name + " - " + machineEvent.Description); - _events.Enqueue(machineEvent); + if (_application.ConnectedMachine == null || _authentication.CurrentUser == null) + { + _pendingEvents.Add(machineEvent); + } + else + { + if (_pendingEvents.Count > 0) + { + var pending = _pendingEvents.ToList(); + _pendingEvents.Clear(); + + foreach (var ev in pending) + { + Log(ev); + } + } - NewLog?.Invoke(this, machineEvent); + LogManager.Log("Logging event " + machineEvent.EventType.Name + " - " + machineEvent.Description); + machineEvent.MachineGuid = _application.ConnectedMachine.Guid; + machineEvent.UserGuid = _authentication.CurrentUser.Guid; + machineEvent.User = _authentication.CurrentUser; + _events.Enqueue(machineEvent); + NewLog?.Invoke(this, machineEvent); + } } /// @@ -222,6 +242,16 @@ namespace Tango.MachineStudio.Common.EventLogging Log(EventTypes.ApplicationException, exception.ToString()); } + /// + /// Logs the specified exception using the . + /// + /// The exception. + /// + public void Log(Exception exception, string description) + { + Log(EventTypes.ApplicationException, description + Environment.NewLine + exception.ToString()); + } + /// /// Logs the specified message using the . /// @@ -238,32 +268,40 @@ namespace Tango.MachineStudio.Common.EventLogging { while (true) { - bool _saveChanges = false; + FlushAll(); + Thread.Sleep(5000); + } + } - while (_events.Count > 0) - { - MachinesEvent ev = null; + /// + /// Immediately saves all pending events to database. + /// + public void FlushAll() + { + bool _saveChanges = false; - if (_events.TryDequeue(out ev)) - { - _db.MachinesEvents.Add(ev); - _saveChanges = true; - } - } + while (_events.Count > 0) + { + MachinesEvent ev = null; - if (_saveChanges) + if (_events.TryDequeue(out ev)) { - try - { - _db.SaveChanges(); - } - catch (Exception ex) - { - LogManager.Log(ex, "Error saving machine event to database."); - } + ev.User = null; + _db.MachinesEvents.Add(ev); + _saveChanges = true; } + } - Thread.Sleep(5000); + if (_saveChanges) + { + try + { + _db.SaveChanges(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving machine event to database."); + } } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/IEventLogger.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/IEventLogger.cs index aeecb4ae6..ce599a398 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/IEventLogger.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/EventLogging/IEventLogger.cs @@ -44,10 +44,21 @@ namespace Tango.MachineStudio.Common.EventLogging /// The exception. void Log(Exception exception); + /// + /// Logs the specified exception using the . + /// + /// The exception. + void Log(Exception exception, String description); + /// /// Logs the specified message using the . /// /// The message. void Log(String message); + + /// + /// Immediately saves all pending events to database. + /// + void FlushAll(); } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Messages/MachineConnectionChangedMessage.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Messages/MachineConnectionChangedMessage.cs new file mode 100644 index 000000000..90820ed47 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Messages/MachineConnectionChangedMessage.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Integration.Services; + +namespace Tango.MachineStudio.Common.Messages +{ + public class MachineConnectionChangedMessage : IStudioMessage + { + public IExternalBridgeClient Machine { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj index 15ab97a27..df553f502 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj @@ -105,6 +105,7 @@ + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs index f94a6c9d9..8b3233ab1 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.xaml.cs @@ -14,6 +14,7 @@ using Tango.MachineStudio.UI.Windows; using Tango.Settings; using Microsoft.Practices.ServiceLocation; using Tango.MachineStudio.Common.EventLogging; +using Tango.BL.Enumerations; namespace Tango.MachineStudio.UI { @@ -49,6 +50,12 @@ namespace Tango.MachineStudio.UI exceptionTrapper = new WpfGlobalExceptionTrapper(); exceptionTrapper.Initialize(this); exceptionTrapper.ApplicationCrashed += ExceptionTrapper_ApplicationCrashed; + + var eventLogger = ServiceLocator.Current.GetInstance(); + if (eventLogger != null) + { + eventLogger.Log(EventTypes.ApplicationStarted, "Application Started!"); + } } #region Global Exception Trapping @@ -74,7 +81,7 @@ namespace Tango.MachineStudio.UI var eventLogger = ServiceLocator.Current.GetInstance(); if (eventLogger != null) { - eventLogger.Log(e.Exception); + eventLogger.Log(e.Exception, "Application Crashed!"); } } catch { } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs index b4b1c5153..52602e6de 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/StudioApplication/DefaultStudioApplicationManager.cs @@ -18,6 +18,8 @@ using Tango.MachineStudio.Common; using Tango.Settings; using System.Windows; using Tango.Integration.Services; +using Tango.MachineStudio.Common.EventLogging; +using Tango.BL.Enumerations; namespace Tango.MachineStudio.UI.StudioApplication { @@ -189,6 +191,13 @@ namespace Tango.MachineStudio.UI.StudioApplication LogManager.Log(ex, "Error disconnecting from machine."); } + var eventLogger = ServiceLocator.Current.GetInstance(); + if (eventLogger != null) + { + eventLogger.Log(EventTypes.ApplicationTerminated, "Application Terminated!"); + eventLogger.FlushAll(); + } + Thread.Sleep(1500); Environment.Exit(0); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs index 54b83a5cc..5776cadc2 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/LoadingViewVM.cs @@ -70,7 +70,6 @@ namespace Tango.MachineStudio.UI.ViewModels { _studioModuleLoader.LoadModules(); _navigationManager.NavigateTo(NavigationView.LoginView); - _eventLogger.Log("Application started successfully"); IsLoading = false; }); } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs index f54a9dae1..81719287b 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs @@ -1,4 +1,5 @@ using GalaSoft.MvvmLight.Ioc; +using GalaSoft.MvvmLight.Messaging; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -19,6 +20,7 @@ using Tango.MachineStudio.Common; using Tango.MachineStudio.Common.Authentication; using Tango.MachineStudio.Common.Diagnostics; using Tango.MachineStudio.Common.EventLogging; +using Tango.MachineStudio.Common.Messages; using Tango.MachineStudio.Common.Modules; using Tango.MachineStudio.Common.Navigation; using Tango.MachineStudio.Common.Notifications; @@ -321,12 +323,27 @@ namespace Tango.MachineStudio.UI.ViewModels { using (_notificationProvider.PushTaskItem("Disconnecting from machine...")) { - _isDisconnecting = true; - InvalidateRelayCommands(); - await ApplicationManager.ConnectedMachine.Disconnect(); - ApplicationManager.ConnectedMachine = null; - _isDisconnecting = false; - InvalidateRelayCommands(); + try + { + _isDisconnecting = true; + InvalidateRelayCommands(); + String serial = ApplicationManager.ConnectedMachine.SerialNumber; + await ApplicationManager.ConnectedMachine.Disconnect(); + ApplicationManager.ConnectedMachine = null; + _eventLogger.Log("Disconnected from machine " + serial); + + PostMessage(new MachineConnectionChangedMessage() { Machine = null }); + } + catch (Exception ex) + { + _eventLogger.Log(ex, "Error disconnecting from machine."); + LogManager.Log(ex, "Could not disconnect from machine."); + } + finally + { + _isDisconnecting = false; + InvalidateRelayCommands(); + } } } @@ -377,12 +394,14 @@ namespace Tango.MachineStudio.UI.ViewModels else { ApplicationManager.ConnectedMachine = x.SelectedMachine; + PostMessage(new MachineConnectionChangedMessage() { Machine = x.SelectedMachine }); _eventLogger.Log(String.Format("Successfully connected to machine {0} via TCP", x.SelectedMachine.SerialNumber)); } } catch (Exception ex) { LogManager.Log(ex); + _eventLogger.Log(ex, "Error connecting to machine " + x.SelectedMachine.SerialNumber); _notificationProvider.ShowError(ex.Message); } @@ -403,6 +422,8 @@ namespace Tango.MachineStudio.UI.ViewModels await x.SelectedMachine.Connect(); x.SelectedMachine.SerialNumber = vm.SelectedMachine.SerialNumber; ApplicationManager.ConnectedMachine = x.SelectedMachine; + + PostMessage(new MachineConnectionChangedMessage() { Machine = x.SelectedMachine }); _eventLogger.Log(String.Format("Successfully connected to machine {0} via USB", x.SelectedMachine.SerialNumber)); SettingsManager.Default.MachineStudio.LastVirtualMachineSerialNumber = vm.SelectedMachine.SerialNumber; SettingsManager.SaveDefaultSettings(); @@ -410,6 +431,7 @@ namespace Tango.MachineStudio.UI.ViewModels catch (Exception ex) { LogManager.Log(ex); + _eventLogger.Log(ex, "Error connecting to machine " + x.SelectedMachine.SerialNumber); _notificationProvider.ShowError(ex.Message); } -- cgit v1.3.1 From 953fc4deb9d94a63afe07d66ccf78ff42f54c3bb Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Tue, 27 Mar 2018 19:51:29 +0300 Subject: Working on logging module! --- Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 1572864 -> 1572864 bytes .../Controls/TimeRuler.cs | 227 +++++++++++++++++++ .../Converters/DateIsInListToBooleanConverter.cs | 30 +++ .../Converters/EventsToTimeRulerTicksConverter.cs | 37 ++++ .../Converters/MachineEventToXConverter.cs | 52 +++++ .../Converters/SecondsToWidthConverter.cs | 27 +++ .../Converters/TimeSpanToXConverter.cs | 32 +++ .../Helpers/TimelineHelper.cs | 16 ++ .../Navigation/LoggingNavigationManager.cs | 22 ++ .../Navigation/LoggingNavigationView.cs | 14 ++ .../Tango.MachineStudio.Logging.csproj | 25 ++- .../ViewModelLocator.cs | 4 + .../ViewModels/DateVM.cs | 22 -- .../ViewModels/MainViewVM.cs | 115 ++++++++-- .../ViewModels/TimelineEventGroup.cs | 28 +++ .../Views/EventsView.xaml | 244 +++++++++++++++++++++ .../Views/EventsView.xaml.cs | 28 +++ .../Views/MainView.xaml | 154 +------------ .../Views/MainView.xaml.cs | 3 + .../Views/TimelineView.xaml | 161 ++++++++++++++ .../Views/TimelineView.xaml.cs | 44 ++++ .../Converters/DateTimeUTCToStringConverter.cs | 31 +++ .../Tango.SharedUI/Tango.SharedUI.csproj | 1 + 24 files changed, 1138 insertions(+), 179 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimeRuler.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/DateIsInListToBooleanConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/EventsToTimeRulerTicksConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/MachineEventToXConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/SecondsToWidthConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Helpers/TimelineHelper.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationManager.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationView.cs delete mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/DateVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineEventGroup.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs create mode 100644 Software/Visual_Studio/Tango.SharedUI/Converters/DateTimeUTCToStringConverter.cs (limited to 'Software/Visual_Studio/MachineStudio') diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 13121b19d..441313330 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 04a2b21ae..abea93449 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimeRuler.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimeRuler.cs new file mode 100644 index 000000000..552f8f416 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Controls/TimeRuler.cs @@ -0,0 +1,227 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace Tango.MachineStudio.Logging.Controls +{ + public class TimeRuler : Control + { + private double _smallStep; + private double _bigStep; + + #region Private Methods + + private static T FindVisualParent(DependencyObject child) where T : DependencyObject + { + // get parent item + DependencyObject parentObject = VisualTreeHelper.GetParent(child); + + // we’ve reached the end of the tree + if (parentObject == null) return null; + + // check if the parent matches the type we’re looking for + T parent = parentObject as T; + if (parent != null) + { + return parent; + } + else + { + // use recursion to proceed with next level + return FindVisualParent(parentObject); + } + } + + #endregion + + #region Properties + + public double RenderWidth + { + get { return (double)GetValue(RenderWidthProperty); } + set { SetValue(RenderWidthProperty, value); } + } + public static readonly DependencyProperty RenderWidthProperty = + DependencyProperty.Register("RenderWidth", typeof(double), typeof(TimeRuler), new FrameworkPropertyMetadata(400.0, FrameworkPropertyMetadataOptions.AffectsRender)); + + public double HorizontalOffset + { + get { return (double)GetValue(HorizontalOffsetProperty); } + set { SetValue(HorizontalOffsetProperty, value); } + } + public static readonly DependencyProperty HorizontalOffsetProperty = + DependencyProperty.Register("HorizontalOffset", typeof(double), typeof(TimeRuler), new PropertyMetadata(0.0, HorizontalOffsetChanged)); + + private static void HorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control = d as TimeRuler; + control.Margin = new Thickness(-control.HorizontalOffset, 0, 0, 0); + control.InvalidateVisual(); + } + + + + #region Zoom + /// + /// Gets or sets the zoom factor for the ruler. The default value is 1.0. + /// + public double Zoom + { + get + { + return (double)GetValue(ZoomProperty); + } + set + { + SetValue(ZoomProperty, value); + this.InvalidateVisual(); + } + } + + private void SetSteps(double value) + { + if (value >= 50) + { + _smallStep = 0.25; + _bigStep = 1; + } + else if (value >= 40) + { + _smallStep = 0.25; + _bigStep = 2; + } + else if (value >= 30) + { + _smallStep = 0.5; + _bigStep = 2; + } + else if (value >= 20) + { + _smallStep = 1; + _bigStep = 5; + } + else if (value >= 10) + { + _smallStep = 1; + _bigStep = 10; + } + else if (value >= 5) + { + _smallStep = 2; + _bigStep = 20; + } + else if (value >= 3) + { + _smallStep = 5; + _bigStep = 30; + } + else if (value >= 1) + { + _smallStep = 30; + _bigStep = 300; + } + else if (value >= 0.5) + { + _smallStep = 60; + _bigStep = 600; + } + } + + /// + /// Identifies the Zoom dependency property. + /// + public static readonly DependencyProperty ZoomProperty = + DependencyProperty.Register("Zoom", typeof(double), typeof(TimeRuler), new FrameworkPropertyMetadata((double)1.0, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(ZoomChanged))); + + private static void ZoomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + (d as TimeRuler).SetSteps((double)e.NewValue); + } + + + #endregion + + #endregion + + #region Constructor + + public TimeRuler() + { + _smallStep = 1; + _bigStep = 10; + FontSize = 10; + this.Loaded += TimeRuler_Loaded; + } + + private void TimeRuler_Loaded(object sender, RoutedEventArgs e) + { + this.InvalidateVisual(); + } + + #endregion + + #region Methods + + /// + /// Participates in rendering operations. + /// + /// The drawing instructions for a specific element. This context is provided to the layout system. + protected override void OnRender(DrawingContext drawingContext) + { + base.OnRender(drawingContext); + + double xDest = RenderWidth; + int start = (int)(HorizontalOffset / Zoom); + + drawingContext.DrawRectangle(Background, new Pen(BorderBrush, 0), new Rect(new Point(start * Zoom, 0.0), new Point(xDest + (start * Zoom) + 100, Height))); + drawingContext.DrawLine(new Pen(BorderBrush, 1), new Point(start * Zoom, Height - 1), new Point(xDest + (start * Zoom) + 100, Height)); + + + double l = (start % _smallStep); + while (l != 0) //I don't know why, but this is needed in order to prevent ruler from flickering on some lower scale factors :/ + { + start += 1; + l = (start % _smallStep); + } + + for (double dUnit = start; dUnit < (RenderWidth / Zoom) + (start) + 10; dUnit += _smallStep) + { + double d = dUnit * (this.Zoom); + + double startHeight; + double endHeight; + + startHeight = Height; + endHeight = ((dUnit % _bigStep == 0) ? (this.ActualHeight / 5) * 1.5 : this.ActualHeight / 5); + + drawingContext.DrawLine(new Pen(Foreground, 1), new Point(d, startHeight), new Point(d, (startHeight - endHeight))); + + double uu = (dUnit % _bigStep); + + if ((dUnit != 0.0) && (uu == 0) && (dUnit < (RenderWidth / Zoom) + start + 10)) + { + double u = dUnit; + TimeSpan t = TimeSpan.FromSeconds((u)); + + FormattedText ft = new FormattedText(t.ToString("g"), + CultureInfo.CurrentCulture, + FlowDirection.LeftToRight, + new Typeface(FontFamily.ToString()), + FontSize, + Foreground); + ft.SetFontWeight(FontWeight); + ft.TextAlignment = TextAlignment.Center; + drawingContext.DrawText(ft, new Point(d, (Height / 2) - (ft.Height / 2) - 2)); + } + } + } + + #endregion + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/DateIsInListToBooleanConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/DateIsInListToBooleanConverter.cs new file mode 100644 index 000000000..cd4f60d4c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/DateIsInListToBooleanConverter.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.MachineStudio.Logging.ViewModels; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class DateIsInListToBooleanConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length < 2 || !(values[0] is DateTime) || !(values[1] is IEnumerable)) + return false; + + var date = (DateTime)values[0]; + var dateList = (IEnumerable)values[1]; + + return dateList.ToList().Exists(x => x.ToLocalTime().ToShortDateString() == date.ToLocalTime().ToShortDateString()); + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/EventsToTimeRulerTicksConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/EventsToTimeRulerTicksConverter.cs new file mode 100644 index 000000000..35df1723b --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/EventsToTimeRulerTicksConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.MachineStudio.Logging.ViewModels; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class EventsToTimeRulerTicksConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + ObservableCollection groups = value as ObservableCollection; + + DateTime maxTime = groups.SelectMany(x => x.Events).Max(x => x.DateTime); + DateTime minTime = groups.SelectMany(x => x.Events).Min(x => x.DateTime); + + List dates = new List(); + + for (DateTime time = minTime; time < maxTime; time = time.AddSeconds(1)) + { + dates.Add(time); + } + + return dates; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/MachineEventToXConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/MachineEventToXConverter.cs new file mode 100644 index 000000000..193a63ffc --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/MachineEventToXConverter.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.BL.Entities; +using Tango.MachineStudio.Logging.Helpers; +using Tango.MachineStudio.Logging.ViewModels; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class MachineEventToXConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length == 3) + { + MachinesEvent ev = values[0] as MachinesEvent; + + if (ev != null) + { + ObservableCollection groups = values[1] as ObservableCollection; + + if (groups.Count > 0) + { + double scale = (double)values[2]; + + DateTime maxTime = groups.SelectMany(x => x.Events).Max(x => x.DateTime); + DateTime minTime = groups.SelectMany(x => x.Events).Min(x => x.DateTime); + + TimeSpan range = maxTime - minTime; + TimeSpan time = maxTime - ev.DateTime; + + time = range - time; + + return TimelineHelper.ConvertTimeToPixels(time, scale); + } + } + } + + return 0.0; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/SecondsToWidthConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/SecondsToWidthConverter.cs new file mode 100644 index 000000000..66e888cc0 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/SecondsToWidthConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.MachineStudio.Logging.Helpers; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class SecondsToWidthConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + double scale = (double)value; + double seconds = System.Convert.ToDouble(parameter.ToString()); + + return TimelineHelper.ConvertTimeToPixels(TimeSpan.FromSeconds(seconds), scale); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs new file mode 100644 index 000000000..4c9f5b569 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Converters/TimeSpanToXConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.MachineStudio.Logging.Helpers; + +namespace Tango.MachineStudio.Logging.Converters +{ + public class TimeSpanToXConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length == 2) + { + TimeSpan time = (TimeSpan)values[0]; + double scale = (double)values[1]; + + return TimelineHelper.ConvertTimeToPixels(time, scale) + 300; + } + + return null; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Helpers/TimelineHelper.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Helpers/TimelineHelper.cs new file mode 100644 index 000000000..6cfe51ba4 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Helpers/TimelineHelper.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Logging.Helpers +{ + public static class TimelineHelper + { + public static double ConvertTimeToPixels(TimeSpan time, double scaleFactor) + { + return ((double)(0.05f * ((double)(time.TotalSeconds) * 20))) * scaleFactor; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationManager.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationManager.cs new file mode 100644 index 000000000..b86df7b0f --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationManager.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Logging; +using Tango.MachineStudio.Common.Navigation; +using Tango.MachineStudio.Logging.Views; + +namespace Tango.MachineStudio.Logging.Navigation +{ + public class LoggingNavigationManager + { + private LogManager LogManager = LogManager.Default; + + public void NavigateTo(LoggingNavigationView view) + { + LogManager.Log(String.Format("Navigating to view {0}...", view.ToString())); + MainView.Instance.TransitionControl.AutoNavigate(view.ToString()); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationView.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationView.cs new file mode 100644 index 000000000..6f4fcbceb --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Navigation/LoggingNavigationView.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Logging.Navigation +{ + public enum LoggingNavigationView + { + EventsView, + TimelineView, + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj index be3e1ef93..8bcdbe016 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Tango.MachineStudio.Logging.csproj @@ -81,13 +81,28 @@ GlobalVersionInfo.cs + + + + + + + + + - + + + EventsView.xaml + MainView.xaml + + TimelineView.xaml + @@ -160,10 +175,18 @@ + + Designer + MSBuild:Compile + Designer MSBuild:Compile + + Designer + MSBuild:Compile + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModelLocator.cs index 76c89000d..ef6923e27 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModelLocator.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModelLocator.cs @@ -1,6 +1,7 @@ using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Ioc; using Microsoft.Practices.ServiceLocation; +using Tango.MachineStudio.Logging.Navigation; using Tango.MachineStudio.Logging.ViewModels; namespace Tango.MachineStudio.Logging @@ -18,6 +19,9 @@ namespace Tango.MachineStudio.Logging { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); SimpleIoc.Default.Register(); + + SimpleIoc.Default.Unregister(); + SimpleIoc.Default.Register(() => new LoggingNavigationManager()); } public static MainViewVM MainViewVM diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/DateVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/DateVM.cs deleted file mode 100644 index fd03d6328..000000000 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/DateVM.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.Core; - -namespace Tango.MachineStudio.Logging.ViewModels -{ - public class DateVM : ExtendedObject - { - public DateTime Date { get; set; } - - public String Description { get; set; } - - public DateVM(DateTime date) - { - Date = date; - Description = date.ToLocalTime().ToShortDateString(); - } - } -} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs index 2b773c1c2..81b0a587c 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/MainViewVM.cs @@ -7,10 +7,12 @@ using System.Text; using System.Threading.Tasks; using Tango.BL; using Tango.BL.Entities; +using Tango.Core.Commands; using Tango.MachineStudio.Common.EventLogging; using Tango.MachineStudio.Common.Messages; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Common.StudioApplication; +using Tango.MachineStudio.Logging.Navigation; using Tango.SharedUI; namespace Tango.MachineStudio.Logging.ViewModels @@ -20,9 +22,9 @@ namespace Tango.MachineStudio.Logging.ViewModels private INotificationProvider _notification; private IStudioApplicationManager _application; private IEventLogger _eventLogger; - private DateVM _realTimeDate; private ObservableCollection _realTimeEvents; private Machine _connectedMachine; + private LoggingNavigationManager _navigation; private Machine _selectedMachine; public Machine SelectedMachine @@ -45,30 +47,88 @@ namespace Tango.MachineStudio.Logging.ViewModels set { _selectedEvent = value; RaisePropertyChangedAuto(); OnSelectedEventChanged(); } } - private ObservableCollection _dates; - public ObservableCollection Dates + private ObservableCollection _dates; + public ObservableCollection Dates { get { return _dates; } set { _dates = value; RaisePropertyChangedAuto(); } } - private DateVM _selectedDate; - public DateVM SelectedDate + private DateTime _selectedDate; + public DateTime SelectedDate { get { return _selectedDate; } set { _selectedDate = value; RaisePropertyChangedAuto(); OnSelectedDateChanged(); } } - public MainViewVM(INotificationProvider notification, IEventLogger eventLogger, IStudioApplicationManager application) + private DateTime _minDate; + public DateTime MinDate { + get { return _minDate; } + set { _minDate = value; RaisePropertyChangedAuto(); } + } + + private DateTime _maxDate; + public DateTime MaxDate + { + get { return _maxDate; } + set { _maxDate = value; RaisePropertyChangedAuto(); } + } + + + private bool _isRealTime; + public bool IsRealTime + { + get { return _isRealTime; } + set { _isRealTime = value; RaisePropertyChangedAuto(); OnSelectedDateChanged(); } + } + + private ObservableCollection _timelineEventGroups; + public ObservableCollection TimelineEventGroups + { + get { return _timelineEventGroups; } + set { _timelineEventGroups = value; RaisePropertyChangedAuto(); } + } + + private TimeSpan _timelineMaxTime; + public TimeSpan TimelineMaxTime + { + get { return _timelineMaxTime; } + set { _timelineMaxTime = value; RaisePropertyChangedAuto(); } + } + + private double _timelineScaleFactor; + public double TimelineScaleFactor + { + get { return _timelineScaleFactor; } + set + { + + if (value < 0.1) value = 0.1; + + _timelineScaleFactor = value; + RaisePropertyChangedAuto(); + } + } + + public RelayCommand DisplayTimelineCommand { get; set; } + + public RelayCommand NavigateToEventsCommand { get; set; } + + public MainViewVM(INotificationProvider notification, IEventLogger eventLogger, IStudioApplicationManager application, LoggingNavigationManager navigation) + { + _navigation = navigation; _application = application; _notification = notification; _eventLogger = eventLogger; - _realTimeDate = new DateVM(DateTime.Now) { Description = "Real Time" }; _realTimeEvents = new ObservableCollection(); _eventLogger.NewLog += _eventLogger_NewLog; + TimelineScaleFactor = 10; + RegisterMessage(OnMachineConnectionChanged); + DisplayTimelineCommand = new RelayCommand(DisplayTimeline); + NavigateToEventsCommand = new RelayCommand(() => _navigation.NavigateTo(LoggingNavigationView.EventsView)); } private void OnMachineConnectionChanged(MachineConnectionChangedMessage msg) @@ -88,7 +148,7 @@ namespace Tango.MachineStudio.Logging.ViewModels { InvokeUI(() => { - _realTimeEvents.Add(machineEvent); + _realTimeEvents.Insert(0, machineEvent); }); } @@ -96,27 +156,30 @@ namespace Tango.MachineStudio.Logging.ViewModels { if (SelectedMachine != null) { - Dates = new ObservableCollection(); + Dates = new ObservableCollection(); if (SelectedMachine == _connectedMachine) { - Dates.Add(_realTimeDate); + IsRealTime = true; } foreach (var day in SelectedMachine.MachinesEvents.GroupBy(x => x.DateTime.DayOfYear).Select(x => x.First().DateTime).OrderByDescending(x => x)) { - Dates.Add(new DateVM(day)); + Dates.Add(day); } + MinDate = Dates.Min(); + MaxDate = Dates.Max(); + SelectedDate = Dates.FirstOrDefault(); } } private void OnSelectedDateChanged() { - if (SelectedDate != null) + if (SelectedDate != null && SelectedMachine != null) { - if (SelectedDate == _realTimeDate) + if (IsRealTime) { Events = _realTimeEvents; } @@ -129,10 +192,34 @@ namespace Tango.MachineStudio.Logging.ViewModels private void OnSelectedEventChanged() { - if (SelectedEvent != null) + if (SelectedEvent != null && SelectedEvent.Type != BL.Enumerations.EventTypes.ApplicationStarted) { _notification.ShowInfo(SelectedEvent.Description); } } + + private void DisplayTimeline(MachinesEvent ev) + { + var events = Events.OrderBy(x => x.DateTime).SkipWhile(x => x != ev).Skip(1).TakeWhile(x => x.DateTime > ev.DateTime && x.Type != BL.Enumerations.EventTypes.ApplicationStarted).ToObservableCollection(); + events.Insert(0, ev); + + TimelineEventGroups = new ObservableCollection(); + + foreach (var group in events.GroupBy(x => x.Group)) + { + TimelineEventGroup evGroup = new TimelineEventGroup(group.Key.ToString().ToWords()); + + foreach (var e in group) + { + evGroup.Events.Add(e); + } + + TimelineEventGroups.Add(evGroup); + } + + TimelineMaxTime = events.Max(x => x.DateTime) - events.Min(x => x.DateTime); + + _navigation.NavigateTo(LoggingNavigationView.TimelineView); + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineEventGroup.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineEventGroup.cs new file mode 100644 index 000000000..978348fd2 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/ViewModels/TimelineEventGroup.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core; + +namespace Tango.MachineStudio.Logging.ViewModels +{ + public class TimelineEventGroup : ExtendedObject + { + public String Name { get; set; } + + public ObservableCollection Events { get; set; } + + public TimelineEventGroup() + { + Events = new ObservableCollection(); + } + + public TimelineEventGroup(String name) : this() + { + Name = name; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml new file mode 100644 index 000000000..a3b4ae6bf --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Real-Time + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml.cs new file mode 100644 index 000000000..b17eea54c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/EventsView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.MachineStudio.Logging.Views +{ + /// + /// Interaction logic for EventsView.xaml + /// + public partial class EventsView : UserControl + { + public EventsView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml index 3d59ee88e..6d841149e 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml @@ -8,153 +8,23 @@ xmlns:autoCompleteMachine="clr-namespace:Tango.MachineStudio.Common.AutoComplete;assembly=Tango.MachineStudio.Common" xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:global="clr-namespace:Tango.MachineStudio.Logging" + xmlns:localConverters="clr-namespace:Tango.MachineStudio.Logging.Converters" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:vm="clr-namespace:Tango.MachineStudio.Logging.ViewModels" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MACHINE EVENTS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml.cs index 160767603..c8d232e86 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/MainView.xaml.cs @@ -20,9 +20,12 @@ namespace Tango.MachineStudio.Logging.Views /// public partial class MainView : UserControl { + public static MainView Instance { get; private set; } + public MainView() { InitializeComponent(); + Instance = this; } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml new file mode 100644 index 000000000..e746f67b3 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs new file mode 100644 index 000000000..53e2362dc --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Logging/Views/TimelineView.xaml.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Tango.MachineStudio.Logging.ViewModels; + +namespace Tango.MachineStudio.Logging.Views +{ + /// + /// Interaction logic for TimelineView.xaml + /// + public partial class TimelineView : UserControl + { + private MainViewVM _vm; + + public TimelineView() + { + InitializeComponent(); + this.Loaded += (_, __) => _vm = DataContext as MainViewVM; + } + + private void UserControl_MouseWheel(object sender, MouseWheelEventArgs e) + { + if (e.Delta > 0) + { + _vm.TimelineScaleFactor += 0.5; + } + else + { + _vm.TimelineScaleFactor -= 0.5; + } + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/DateTimeUTCToStringConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/DateTimeUTCToStringConverter.cs new file mode 100644 index 000000000..0a9c47e48 --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Converters/DateTimeUTCToStringConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace Tango.SharedUI.Converters +{ + public class DateTimeUTCToStringConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value != null) + { + DateTime date = (DateTime)value; + return date.ToLocalTime().ToString(parameter.ToString()); + } + else + { + return null; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj index 1ac652edf..ef5dae666 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj +++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj @@ -97,6 +97,7 @@ + -- cgit v1.3.1